package com.sailfish.springbootdemo.service.db1;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sailfish.springbootdemo.common.DB1EmailTemplates;
import com.sailfish.springbootdemo.common.StrToCompanys;
import com.sailfish.springbootdemo.configs.UserHeaderHolder;
import com.sailfish.springbootdemo.dao.db1.*;
import com.sailfish.springbootdemo.dao.db4.UserDao;
import com.sailfish.springbootdemo.pojo.Result;
import com.sailfish.springbootdemo.pojo.db1.*;
import com.sailfish.springbootdemo.pojo.db2.MailAddress;
import com.sailfish.springbootdemo.pojo.db4.Operate;
import com.sailfish.springbootdemo.pojo.db4.User;
import com.sailfish.springbootdemo.service.db2.ThirdApiService;
import com.sailfish.springbootdemo.service.db4.OperateService;
import com.sailfish.springbootdemo.utils.CommonUtils;
import com.sailfish.springbootdemo.utils.FileConverterUtils;
import com.sailfish.springbootdemo.utils.ResultUtil;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;

@Service
public class PcbaDeviceServiceImpl implements PcbaDeviceService {

    @Autowired
    private PcbaDeviceDao pcbaDeviceDao;

    @Autowired
    private PcbaDeviceRelatedDeviceParamDao pcbaDeviceRelatedDeviceParamDao;

    @Autowired
    private PcbaDeviceRelatedTechParamDao pcbaDeviceRelatedTechParamDao;

    @Autowired
    private PcbaDeviceRelatedTechParamActualDao pcbaDeviceRelatedTechParamActualDao;

    @Autowired
    private TechDeviceParamTypeDao techDeviceParamTypeDao;

    @Autowired
    private PcbaDeviceParamTypeDao pcbaDeviceParamTypeDao;

    @Autowired
    private AuditHistoryDao auditHistoryDao;

    @Autowired
    private TechDeviceParamDao techDeviceParamDao;

    @Autowired
    private PcbaDeviceParamDao pcbaDeviceParamDao;

    @Autowired
    private PcbaDeviceResourceDao pcbaDeviceResourceDao;

    @Autowired
    private BrandDao brandDao;

    @Autowired
    private DeviceAgeHistoryDao deviceAgeHistoryDao;

    @Autowired
    private BrandTypeDao brandTypeDao;

    @Autowired
    private PcbaLineDao pcbaLineDao;

    @Autowired
    private PcbaCompanyDao pcbaCompanyDao;

    @Autowired
    private PcbaWorkshopDao pcbaWorkshopDao;

    @Autowired
    private PcbaProcessDao pcbaProcessDao;

    @Autowired
    private PcbaDeviceTypeDao pcbaDeviceTypeDao;

    @Autowired
    private UpkeepDao upkeepDao;

    @Autowired
    private UpkeepAuditDao upkeepAuditDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private MaintenanceConfigDao maintenanceConfigDao;

    @Autowired
    private PcbaDeviceAgeHandledDao pcbaDeviceAgeHandledDao;

    @Autowired
    private CoreAlgorithmService coreAlgorithmService;

    @Value("${personal.config.file.file-save-url}")
    private String fileSaveUrl;

    @Value("${personal.config.env}")
    private String env;

    @Value("${personal.config.sso.trusted-redirect-uri}")
    private String trustedRedirectUri;

    @Qualifier("MysqlTransactionManager1")
    @Autowired
    private DataSourceTransactionManager transactionManager1;

    @Autowired
    private OperateService operateService;

    @Autowired
    private ThirdApiService thirdApiService;

    private String operateSmallType = "设备管理";

    @Autowired
    private StrToCompanys strToCompanys;

    @Override
    public Result getAllPcbaDevice(Integer pcbaDeviceTypeId, String searchValue, Integer status, Integer pageSize, Integer page, Integer pcbaCompanyId, Integer pcbaWorkshopId, Integer pcbaProcessId, Integer isFilledUpkeep) {
        try {
            if (pageSize == null || !CommonUtils.isNumeric(pageSize.toString())) {
                return ResultUtil.error(500, "错误参数pageSize", "Error Param pageSize", null);
            }
            if (page == null || !CommonUtils.isNumeric(page.toString())) {
                return ResultUtil.error(500, "错误参数page", "Error Param page", null);
            }
            int begin = (page - 1) * pageSize;
            List<Integer> companyIdList = strToCompanys.getPcbaCompanyIdListFromStr();
            //System.out.println("begin===" + begin);
            //System.out.println("pageSize===" + pageSize);
            List<PcbaDevice> list = pcbaDeviceDao.getAllPcbaDevice(pcbaDeviceTypeId, searchValue, status, begin, pageSize, pcbaCompanyId, pcbaWorkshopId, pcbaProcessId, isFilledUpkeep, companyIdList);
            for (PcbaDevice pcbaDevice : list) {
                PcbaDeviceResource pcbaDeviceResource = pcbaDeviceResourceDao.getById(pcbaDevice.getPcbaDeviceResourceId());
                pcbaDeviceResource.setBrand(brandDao.getBrandById(pcbaDeviceResource.getBrandId()));
                pcbaDeviceResource.setBrandType(brandTypeDao.getBrandTypeById(pcbaDeviceResource.getBrandTypeId()));
                pcbaDeviceResource.setPcbaDeviceType(pcbaDeviceTypeDao.getById(pcbaDeviceResource.getPcbaDeviceTypeId()));
                pcbaDevice.setPcbaDeviceResource(pcbaDeviceResource);

                pcbaDevice.setUpkeepList(upkeepDao.getUpkeepByDeviceId(pcbaDevice.getAssetNumber(), null));
                pcbaDevice.setUpkeepAuditList(upkeepAuditDao.getUpkeepAuditByDeviceId(pcbaDevice.getAssetNumber(), null, null));

                PcbaLine pcbaLine = pcbaLineDao.getPcbaLineById(pcbaDevice.getPcbaLineId());
                pcbaLine.setPcbaCompany(pcbaCompanyDao.getPcbaCompanyById(pcbaLine.getPcbaCompanyId()));
                pcbaLine.setPcbaWorkshop(pcbaWorkshopDao.getPcbaWorkshopById(pcbaLine.getPcbaWorkshopId()));
                pcbaLine.setPcbaProcess(pcbaProcessDao.getPcbaProcessById(pcbaLine.getPcbaProcessId()));
                pcbaDevice.setPcbaLine(pcbaLine);
            }
            List<PcbaDevice> list2 = pcbaDeviceDao.getAllPcbaDevice(pcbaDeviceTypeId, searchValue, status, null, null, pcbaCompanyId, pcbaWorkshopId, pcbaProcessId, isFilledUpkeep, companyIdList);
            return ResultUtil.tableSuccess(page, pageSize, list2.size(), list);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @Transactional(transactionManager = "MysqlTransactionManager1")
    @Override
    public Result deleteById(Integer pcbaDeviceId) {
        try {
            if (pcbaDeviceId == null || "".equals(pcbaDeviceId.toString())) {
                return ResultUtil.error(500, "缺少参数pcbaDeviceId", "Miss Param pcbaDeviceId", null);
            }

            String userId = UserHeaderHolder.getUserId();
            PcbaDevice oldPcbaDevice = pcbaDeviceDao.getById(pcbaDeviceId);

            // 级联触发 线体的最终状态
            coreAlgorithmService.cascadeUpdateLineFinalStatus(2, null, pcbaDeviceId, null);

            pcbaDeviceDao.deleteById(pcbaDeviceId);
            pcbaDeviceRelatedDeviceParamDao.deleteDeviceRelatedParam(pcbaDeviceId);

            // 1）校验线体资产信息完整性
            // 2）线体基线整线能力认证状态改为`待提交审核`，其他情况不用变【功能已完成】

            // 1)
            // 判断 线体中 除了该设备的其他设备的资产是否全部填写
            List<PcbaDevice> list = pcbaDeviceDao.getPcbaDeviceByLine(oldPcbaDevice.getPcbaLineId());
            boolean b = true;
            for (PcbaDevice device : list) {
                if (!device.getPcbaDeviceId().equals(pcbaDeviceId)) {
                    if ((device.getAssetNumber() == null || "".equals(device.getAssetNumber())) && !device.getPcbaDeviceId().equals(pcbaDeviceId)) {
                        b = false;
                    }
                }
            }
            if (b) {
                PcbaLine oldPcbaLine = pcbaLineDao.getPcbaLineById(oldPcbaDevice.getPcbaLineId());
                PcbaLine updatePcbaLine = new PcbaLine();
                updatePcbaLine.setUpdateTime(new Date());
                updatePcbaLine.setStatus(1);
                updatePcbaLine.setPcbaLineId(oldPcbaDevice.getPcbaLineId());
                pcbaLineDao.updatePcbaLine(updatePcbaLine);

                // 操作日志
                operateService.addOperate(new Operate(1, Integer.parseInt(userId), operateSmallType, 3, 1, new Date(), JSONObject.toJSONString(oldPcbaLine), JSONObject.toJSONString(updatePcbaLine)));
            }

            // 2)
            pcbaLineDao.auditPcbaLineParamBase(oldPcbaDevice.getPcbaLineId(), 4, "");
            //pcbaLineDao.auditPcbaLineTechActual("", oldPcbaDevice.getPcbaLineId(), 4, new Date());
            pcbaLineDao.updatePcbaLineLockDeclare(oldPcbaDevice.getPcbaLineId(), 2);

            // 操作日志
            operateService.addOperate(new Operate(1, Integer.parseInt(userId), operateSmallType, 2, 1, new Date(), JSONObject.toJSONString(oldPcbaDevice), null));

            return ResultUtil.success(null);
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @Transactional(transactionManager = "MysqlTransactionManager1")
    @Override
    public Result updatePcbaDevice(PcbaDevice pcbaDevice) {
        try {
            Integer pcbaDeviceId = pcbaDevice.getPcbaDeviceId();
            PcbaDevice p = pcbaDeviceDao.getById(pcbaDeviceId);
            Integer pcbaLineId = p.getPcbaLineId();
            List<PcbaDevice> list = pcbaDeviceDao.getPcbaDeviceByLine(pcbaLineId);

            if (pcbaDevice.getPcbaDeviceId() == null || "".equals(pcbaDevice.getPcbaDeviceId().toString())) {
                return ResultUtil.error(500, "缺少参数pcbaDeviceId", "Miss Param pcbaDeviceId", null);
            }

            String userId = UserHeaderHolder.getUserId();
            PcbaDevice oldPcbaDevice = pcbaDeviceDao.getById(pcbaDevice.getPcbaDeviceId());
            String old_assetNumber = oldPcbaDevice.getAssetNumber() != null ? oldPcbaDevice.getAssetNumber() : "";
            Date old_productTime = oldPcbaDevice.getProductTime();
            String old_purpose = oldPcbaDevice.getPurpose() != null ? oldPcbaDevice.getPurpose() : "";

            pcbaDevice.setUpdateTime(new Date());
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            if (pcbaDevice.getProductTimeStr() == null || "".equals(pcbaDevice.getProductTimeStr())) {
                return ResultUtil.error(500, "缺少参数productTimeStr", "Miss Param productTimeStr", null);
            }

            // 判断设备资产是否唯一
            List<PcbaDevice> pcbaDeviceList = pcbaDeviceDao.judgeAssetNumber(pcbaDevice.getAssetNumber(), pcbaDeviceId);
            if (pcbaDeviceList.size() > 0) {
                return ResultUtil.error(500, "当前已存在相同资产", "Already Exist Same Asset Number", null);
            }
            String old_productTimeStr = "";
            if (old_productTime != null) {
                old_productTimeStr = format.format(old_productTime);
            }

            Date date = format.parse(pcbaDevice.getProductTimeStr());
            pcbaDevice.setProductTime(date);
            // 设备状态后面可能需要结合多种情况再做判断，目前 设置为 1 即正常
            pcbaDevice.setStatus(1);
            pcbaDeviceDao.updatePcbaDevice(pcbaDevice);

            String newPurpose = pcbaDevice.getPurpose() != null ? pcbaDevice.getPurpose() : "";

            //只要资产编号、出厂日期、用途 任何一个发生变化，则将线体的状态变成待提交审核
            if (!old_assetNumber.equals(pcbaDevice.getAssetNumber()) || !old_productTimeStr.equals(pcbaDevice.getProductTimeStr()) || !old_purpose.equals(newPurpose)) {
                pcbaLineDao.auditPcbaLineParamBase(oldPcbaDevice.getPcbaLineId(), 4, "");
                //pcbaLineDao.auditPcbaLineTechActual("", oldPcbaDevice.getPcbaLineId(), 4, new Date());
            }

            // 操作日志
            operateService.addOperate(new Operate(1, Integer.parseInt(userId), operateSmallType, 3, 1, new Date(), JSONObject.toJSONString(oldPcbaDevice), JSONObject.toJSONString(pcbaDevice)));

            // 判断该线体的所有设备是否均已填写资产，如果均已填写，则将线体是否完善资产信息变为1
            boolean b = true;
            for (PcbaDevice device : list) {
                if ((device.getAssetNumber() == null || "".equals(device.getAssetNumber())) && !device.getPcbaDeviceId().equals(pcbaDeviceId)) {
                    b = false;
                }
            }
            if (b) {
                PcbaLine oldPcbaLine = pcbaLineDao.getPcbaLineById(pcbaLineId);

                PcbaLine updatePcbaLine = new PcbaLine();
                updatePcbaLine.setUpdateTime(new Date());
                updatePcbaLine.setStatus(1);
                updatePcbaLine.setPcbaLineId(pcbaLineId);
                pcbaLineDao.updatePcbaLine(updatePcbaLine);

                // 操作日志
                operateService.addOperate(new Operate(1, Integer.parseInt(userId), operateSmallType, 3, 1, new Date(), JSONObject.toJSONString(oldPcbaLine), JSONObject.toJSONString(updatePcbaLine)));

            }

            // 级联触发 线体的最终状态
            coreAlgorithmService.cascadeUpdateLineFinalStatus(2, null, pcbaDeviceId, null);

            //将触发pcba能力逻辑的参数返回
            JSONObject jo = new JSONObject();
            jo.put("type", 4);
            jo.put("beforeStr", oldPcbaDevice.getPurpose());
            jo.put("afterStr", pcbaDevice.getPurpose());
            return ResultUtil.success(jo);
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @Override
    public PcbaDevice getPcbaDeviceById(Integer pcbaDeviceId) {
        PcbaDevice p = pcbaDeviceDao.getById(pcbaDeviceId);
        p.setPcbaLine(pcbaLineDao.getPcbaLineById(p.getPcbaLineId()));
        PcbaDeviceResource pr = pcbaDeviceResourceDao.getById(p.getPcbaDeviceResourceId());
        pr.setBrand(brandDao.getBrandById(pr.getBrandId()));
        pr.setBrandType(brandTypeDao.getBrandTypeById(pr.getBrandTypeId()));
        pr.setPcbaDeviceType(pcbaDeviceTypeDao.getById(pr.getPcbaDeviceTypeId()));
        p.setPcbaDeviceResource(pr);
        return p;
    }

    @Override
    @Transactional(transactionManager = "MysqlTransactionManager1")
    public Result adjustDeviceSort(String type, Integer pcbaLineId, Integer pcbaDeviceId) {
        try {
            if (type == null || "".equals(type)) {
                return ResultUtil.error(500, "缺少参数type", "Miss Param type", null);
            }
            if (pcbaLineId == null || "".equals(pcbaLineId.toString())) {
                return ResultUtil.error(500, "缺少参数pcbaLineId", "Miss Param pcbaLineId", null);
            }
            if (pcbaDeviceId == null || "".equals(pcbaDeviceId.toString())) {
                return ResultUtil.error(500, "缺少参数pcbaDeviceId", "Miss Param pcbaDeviceId", null);
            }
            if (!"up".equals(type) && !"down".equals(type)) {
                return ResultUtil.error(500, "type参数错误", "type Param Error", null);
            }
            List<PcbaDevice> pcbaDeviceList = pcbaDeviceDao.getPcbaDeviceByLine(pcbaLineId);
            if (pcbaDeviceList.size() == 0) {
                return ResultUtil.error(500, "设备列表为空", "DeviceList Is Null", null);
            }

            if ("up".equals(type)) {
                // 向上调整
                if (pcbaDeviceId.equals(pcbaDeviceList.get(0).getPcbaDeviceId())) {
                    return ResultUtil.error(500, "不能调整", "Can Not Adjust", null);
                }
                int index = 0;
                for (int a = 0; a < pcbaDeviceList.size(); a++) {
                    if (pcbaDeviceId.equals(pcbaDeviceList.get(a).getPcbaDeviceId())) {
                        index = a;
                        break;
                    }
                }
                Collections.swap(pcbaDeviceList, index, index - 1);
                for (int a = 0; a < pcbaDeviceList.size(); a++) {
                    pcbaDeviceDao.updatePcbaDeviceSort(pcbaDeviceList.get(a).getPcbaDeviceId(), a + 1);
                }

                PcbaLine updatePcbaLine = new PcbaLine();
                updatePcbaLine.setPcbaLineId(pcbaLineId);
                updatePcbaLine.setUpdateTime(new Date());
                pcbaLineDao.updatePcbaLine(updatePcbaLine);

            } else {
                // 向下调整
                if (pcbaDeviceId.equals(pcbaDeviceList.get(pcbaDeviceList.size() - 1).getPcbaDeviceId())) {
                    return ResultUtil.error(500, "不能调整", "Can Not Adjust", null);
                }
                int index = 0;
                for (int a = 0; a < pcbaDeviceList.size(); a++) {
                    if (pcbaDeviceId.equals(pcbaDeviceList.get(a).getPcbaDeviceId())) {
                        index = a;
                        break;
                    }
                }
                Collections.swap(pcbaDeviceList, index, index + 1);
                for (int a = 0; a < pcbaDeviceList.size(); a++) {
                    pcbaDeviceDao.updatePcbaDeviceSort(pcbaDeviceList.get(a).getPcbaDeviceId(), a + 1);
                }

                PcbaLine updatePcbaLine = new PcbaLine();
                updatePcbaLine.setPcbaLineId(pcbaLineId);
                updatePcbaLine.setUpdateTime(new Date());
                pcbaLineDao.updatePcbaLine(updatePcbaLine);
            }
            // 状态改为待提交审核
            pcbaLineDao.auditPcbaLineParamBase(pcbaLineId, 4, "");

            // 级联触发 线体的最终状态
            coreAlgorithmService.cascadeUpdateLineFinalStatus(3, null, null, pcbaLineId);
            //pcbaLineDao.auditPcbaLineTechActual("", pcbaLineId, 4, new Date());
            return ResultUtil.success(null);
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @Override
    // @Transactional(transactionManager = "MysqlTransactionManager1")
    public Result addOrUpdateTechAndParamRelatedActual(String data) {
        try {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            JSONObject jsonObject = JSONObject.parseObject(data);
            String mode = jsonObject.getString("mode");
            JSONArray jsonArray = jsonObject.getJSONArray("pcbaDeviceRelatedTechParamList");
            Date d = new Date();
            String beginTimeStr = jsonObject.get("beginTimeStr") != null && !"".equals(jsonObject.get("beginTimeStr")) ? jsonObject.get("beginTimeStr").toString() : null;
            String endTimeStr = jsonObject.get("endTimeStr") != null && !"".equals(jsonObject.get("endTimeStr")) ? jsonObject.get("endTimeStr").toString() : null;
            String paramsStatus = jsonObject.get("paramsStatus") != null && !"".equals(jsonObject.get("paramsStatus")) ? jsonObject.get("paramsStatus").toString() : null;
            if (beginTimeStr == null || "".equals(beginTimeStr)) {
                return ResultUtil.error(500, "缺少参数beginTimeStr", "Miss Param beginTimeStr", null);
            }
            if (endTimeStr == null || "".equals(endTimeStr)) {
                return ResultUtil.error(500, "缺少参数endTimeStr", "Miss Param endTimeStr", null);
            }
            if (paramsStatus == null || "".equals(paramsStatus)) {
                return ResultUtil.error(500, "缺少参数paramsStatus", "Miss Param paramsStatus", null);
            }

            String userId = UserHeaderHolder.getUserId();

            if ("update".equals(mode)) {
                // 修改设备的 is_filled_tech_params_actual
                Integer pcbaDeviceId = jsonObject.getInteger("pcbaDeviceId");
                if (pcbaDeviceId == null || "".equals(pcbaDeviceId.toString())) {
                    return ResultUtil.error(500, "缺少参数pcbaDeviceId", "Miss Param pcbaDeviceId", null);
                }

                PcbaDevice oldPcbaDevice = pcbaDeviceDao.getById(pcbaDeviceId);

                Date beginTime = format.parse(beginTimeStr);
                Date endTime = format.parse(endTimeStr);
                PcbaDevice updatePcbaDevice = new PcbaDevice();
                updatePcbaDevice.setIsFilledTechParamsActual(1);
                updatePcbaDevice.setPcbaDeviceId(pcbaDeviceId);
                updatePcbaDevice.setBeginTime(beginTime);
                updatePcbaDevice.setEndTime(endTime);
                updatePcbaDevice.setParamsStatus(Integer.parseInt(paramsStatus));
                updatePcbaDevice.setSubmitter(Integer.parseInt(userId));
                pcbaDeviceDao.updatePcbaDevice(updatePcbaDevice);

                // 操作日志
                operateService.addOperate(new Operate(1, Integer.parseInt(userId), operateSmallType, 3, 1, new Date(), JSONObject.toJSONString(oldPcbaDevice), JSONObject.toJSONString(updatePcbaDevice)));

                List<PcbaDeviceRelatedTechParamActual> oldPcbaDeviceRelatedTechParamActualList = pcbaDeviceRelatedTechParamActualDao.getAllByDeviceIdActual(pcbaDeviceId);

                // 删除 实际能力 关联参数表
                //pcbaDeviceRelatedTechParamActualDao.deleteDeviceRelatedParamActual(pcbaDeviceId);
                // 操作日志
                //operateService.addOperate(new Operate(1, Integer.parseInt(userId), operateSmallType, 2, 1, new Date(), JSONObject.toJSONString(oldPcbaDeviceRelatedTechParamActualList), null));
                List<PcbaDeviceRelatedTechParamActual> list = new ArrayList<>();
                // 新增 实际能力 关联参数表
                for (int a = 0; a < jsonArray.size(); a++) {
                    JSONObject jo = (JSONObject) jsonArray.get(a);
                    String techDeviceParamKey = jo.get("techDeviceParamKey").toString();
                    int pcbaDeviceTypeId = Integer.parseInt(jo.get("pcbaDeviceTypeId").toString());
                    String techDeviceParamValue = jo.get("techDeviceParamValue").toString();

                    PcbaDeviceRelatedTechParamActual pdrtpa = pcbaDeviceRelatedTechParamActualDao.getPcbaDeviceRelatedTechParamActualByPcbaDeviceIdAndKey(pcbaDeviceId, techDeviceParamKey);
                    if (pdrtpa != null) {
                        // update
                        //pdrtpa.setTechDeviceParamValueAudit(pdrtpa.getTechDeviceParamValue());
                        pdrtpa.setTechDeviceParamValue(techDeviceParamValue);
                        pdrtpa.setUpdateTime(d);
                        pcbaDeviceRelatedTechParamActualDao.updateDeviceRelatedParamActual(pdrtpa);
                        list.add(pdrtpa);
                    } else {
                        // add
                        PcbaDeviceRelatedTechParamActual pcbaDeviceRelatedTechParamActual = new PcbaDeviceRelatedTechParamActual();
                        pcbaDeviceRelatedTechParamActual.setCreateTime(d);
                        pcbaDeviceRelatedTechParamActual.setPcbaDeviceId(pcbaDeviceId);
                        pcbaDeviceRelatedTechParamActual.setTechDeviceParamKey(techDeviceParamKey);
                        pcbaDeviceRelatedTechParamActual.setPcbaDeviceTypeId(pcbaDeviceTypeId);
                        pcbaDeviceRelatedTechParamActual.setTechDeviceParamValue(techDeviceParamValue);
                        pcbaDeviceRelatedTechParamActualDao.addTechRelatedParamActual(pcbaDeviceRelatedTechParamActual);
                        list.add(pcbaDeviceRelatedTechParamActual);
                    }
                }

                // 操作日志
                operateService.addOperate(new Operate(1, Integer.parseInt(userId), operateSmallType, 3, 1, new Date(), JSONObject.toJSONString(oldPcbaDeviceRelatedTechParamActualList), JSONObject.toJSONString(list)));

                /*if("3".equals(paramsStatus)){
                    // 添加 审核记录
                    AuditHistory addAuditHistory = new AuditHistory();
                    addAuditHistory.setAuditType(1);
                    addAuditHistory.setCreateTime(d);
                    addAuditHistory.setSubmitUserId(Integer.parseInt(userId));
                    addAuditHistory.setAuditUserId(null);
                    addAuditHistory.setAuditStatus(Integer.parseInt(paramsStatus));
                    addAuditHistory.setAuditNotes(null);
                    addAuditHistory.setRelatedId(pcbaDeviceId);
                    auditHistoryDao.addAuditHistory(addAuditHistory);
                }*/

                // 级联触发 线体的最终状态
                coreAlgorithmService.cascadeUpdateLineFinalStatus(2, null, pcbaDeviceId, null);

                if (Integer.parseInt(paramsStatus) == 3) {
                    //发送邮件
                    try {
                        List<User> userList = new ArrayList<>();
                        PcbaDevice pcbaDevice = pcbaDeviceDao.getById(pcbaDeviceId);
                        if (pcbaDevice != null) {
                            PcbaLine pcbaLine = pcbaLineDao.getPcbaLineById(pcbaDevice.getPcbaLineId());
                            if (pcbaLine != null) {
                                PcbaCompany pcbaCompany = pcbaCompanyDao.getPcbaCompanyById(pcbaLine.getPcbaCompanyId());
                                if (pcbaCompany != null) {
                                    String emailOwners5 = pcbaCompany.getEmailOwners5();
                                    if (emailOwners5 != null && !"".equals(emailOwners5)) {
                                        String[] split = emailOwners5.split(",");
                                        for (String s : split) {
                                            if (s.contains("/")) {
                                                String[] strings = s.split("\\/");
                                                if (strings.length == 2) {
                                                    String domainAccount = strings[1];
                                                    if (domainAccount != null && !"".equals(domainAccount)) {
                                                        User u = userDao.getUserInfoByDomainAccount(domainAccount);
                                                        if (u != null) {
                                                            userList.add(u);
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        List<MailAddress> mailAddressList = new ArrayList<>();
                        for (User user : userList) {
                            if(user.getEmail().contains(",")){
                                String[] emailsArr = user.getEmail().split(",");
                                for (String email : emailsArr) {
                                    MailAddress mailAddress = new MailAddress();
                                    mailAddress.setMailAddress(email);
                                    mailAddress.setType(0);
                                    mailAddressList.add(mailAddress);
                                }
                            }else{
                                MailAddress mailAddress = new MailAddress();
                                mailAddress.setMailAddress(user.getEmail());
                                mailAddress.setType(0);
                                mailAddressList.add(mailAddress);
                            }
                        }

                        String companyName = "";
                        String workshopName = "";
                        String lineName = "";
                        if(pcbaDevice != null){
                            Integer pcbaLineId = pcbaDevice.getPcbaLineId();
                            PcbaLine pcbaLine = pcbaLineDao.getPcbaLineById(pcbaLineId);
                            PcbaCompany pcbaCompany = pcbaCompanyDao.getPcbaCompanyById(pcbaLine.getPcbaCompanyId());
                            companyName = pcbaCompany.getPcbaCompanyNameCn();
                            PcbaWorkshop pcbaWorkshop = pcbaWorkshopDao.getPcbaWorkshopById(pcbaLine.getPcbaWorkshopId());
                            workshopName = pcbaWorkshop.getPcbaWorkshopNameCn();
                            lineName = pcbaLine.getPcbaLineNameCn();
                        }


                        String mailContent = "<html><body>" +
                                "<p>主题：" + DB1EmailTemplates.DEVICE_TECH_PARAMS_TITLE + "</p>" +
                                "<p>设备资产编号：" + ((pcbaDevice != null && pcbaDevice.getAssetNumber() != null) ? pcbaDevice.getAssetNumber() : "") + "</p>" +
                                "<p>所在线体：" + companyName + "/" + workshopName + "/" + lineName + "</p>" +
                                "<p>网页链接：" + "<a href='" + trustedRedirectUri + DB1EmailTemplates.DEVICE_TECH_PARAMS_WEB_URL + "'>点击跳转</a>" +  "</p>" +
                                "</html></body>";

                        if (mailAddressList.size() > 0) {
                            Result result = thirdApiService.sendMail("", DB1EmailTemplates.DEVICE_TECH_PARAMS_TITLE, DB1EmailTemplates.DEVICE_TECH_PARAMS_MAIL_CONTENT_TITLE,
                                    mailContent, "10086", mailAddressList, null, null, null, null, 2, null);
                            if (result.getCode() == 200) {
                                System.out.println(CommonUtils.formatCurrentTime() + "==========================================");
                                System.out.println("设备实际工艺能力邮件,发送成功");
                            } else {
                                System.out.println(CommonUtils.formatCurrentTime() + "==========================================");
                                System.out.println("设备实际工艺能力邮件,发送失败:" + result.getMsgCn());
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        System.out.println(CommonUtils.formatCurrentTime() + "==========================================");
                        System.out.println("设备实际工艺能力邮件：" + e.getMessage());
                    }
                }

                return ResultUtil.success(null);
            }/*else if("update".equals(mode)){
                return ResultUtil.error(500, "更新逻辑待完成", "Error Param mode", null);
                //return ResultUtil.success(null);
            }*/
            return ResultUtil.error(500, "mode 参数错误", "Error Param mode", null);
        } catch (Exception e) {
            //TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @Override
    public Result getTechParamValueAndTechParamValueActual(Integer pcbaDeviceId, Integer pcbaDeviceResourceId, Integer pcbaDeviceTypeId) {
        try {
            if (pcbaDeviceId == null || "".equals(pcbaDeviceId.toString())) {
                return ResultUtil.error(500, "缺少参数pcbaDeviceId", "Miss Param pcbaDeviceId", null);
            }
            if (pcbaDeviceResourceId == null || "".equals(pcbaDeviceResourceId.toString())) {
                return ResultUtil.error(500, "缺少参数pcbaDeviceResourceId", "Miss Param pcbaDeviceResourceId", null);
            }
            if (pcbaDeviceTypeId == null || "".equals(pcbaDeviceTypeId.toString())) {
                return ResultUtil.error(500, "缺少参数pcbaDeviceTypeId", "Miss Param pcbaDeviceTypeId", null);
            }

            List<TechDeviceParamType> techDeviceParamTypeList = techDeviceParamTypeDao.getAllTechDeviceParamTypeByDeviceType(pcbaDeviceTypeId, "");

            // 根据 pcbaResourceId 查询 宣称能力
            List<PcbaDeviceRelatedTechParam> pcbaDeviceRelatedTechParamList = pcbaDeviceRelatedTechParamDao.getAllByDeviceResourceId(pcbaDeviceResourceId);

            // 根据 pcbaDeviceId 查询 实际能力
            List<PcbaDeviceRelatedTechParamActual> pcbaDeviceRelatedTechParamActualList = pcbaDeviceRelatedTechParamActualDao.getAllByDeviceIdActual(pcbaDeviceId);


            List<Map<String, Object>> list = new ArrayList<>();
            for (TechDeviceParamType techDeviceParamType : techDeviceParamTypeList) {
                Map<String, Object> map1 = new HashMap<>();
                List<Map<String, Object>> children = new ArrayList<>();

                List<TechDeviceParam> allTechDeviceParam = techDeviceParamDao.getAllTechDeviceParam(pcbaDeviceTypeId, techDeviceParamType.getTechDeviceParamTypeId(), null);
                for (TechDeviceParam techDeviceParam : allTechDeviceParam) {
                    String techDeviceParamKey = techDeviceParam.getTechDeviceParamKey();
                    PcbaDeviceRelatedTechParam pcbaDeviceRelatedTechParamByKeyAndDeviceResourceId = pcbaDeviceRelatedTechParamDao.getPcbaDeviceRelatedTechParamByKeyAndDeviceResourceId(techDeviceParamKey, pcbaDeviceResourceId);
                    PcbaDeviceRelatedTechParamActual pcbaDeviceRelatedTechParamActualByPcbaDeviceIdAndKey = pcbaDeviceRelatedTechParamActualDao.getPcbaDeviceRelatedTechParamActualByPcbaDeviceIdAndKey(pcbaDeviceId, techDeviceParamKey);
                    Map<String, Object> map2 = new HashMap<>();
                    if (pcbaDeviceRelatedTechParamByKeyAndDeviceResourceId != null) {
                        map2.put("label", techDeviceParam.getTechDeviceParamNameCn());
                        map2.put("value", pcbaDeviceRelatedTechParamByKeyAndDeviceResourceId.getTechDeviceParamValue());
                        map2.put("key", techDeviceParamKey);
                        map2.put("notes", (techDeviceParam.getNotes() != null) ? techDeviceParam.getNotes() : "");
                        map2.put("techDeviceParamPicture", (techDeviceParam.getTechDeviceParamPicture() != null) ? techDeviceParam.getTechDeviceParamPicture() : "");
                        map2.put("type", 1);
                        if (pcbaDeviceRelatedTechParamActualByPcbaDeviceIdAndKey != null) {
                            map2.put("valueActual", pcbaDeviceRelatedTechParamActualByPcbaDeviceIdAndKey.getTechDeviceParamValue());
                            map2.put("valueActualAudit", pcbaDeviceRelatedTechParamActualByPcbaDeviceIdAndKey.getTechDeviceParamValueAudit());
                        } else {
                            map2.put("valueActual", "");
                            map2.put("valueActualAudit", "");
                        }
                        children.add(map2);
                    } else {
                        map2.put("label", techDeviceParam.getTechDeviceParamNameCn());
                        map2.put("value", "");
                        map2.put("key", techDeviceParamKey);
                        map2.put("notes", (techDeviceParam.getNotes() != null) ? techDeviceParam.getNotes() : "");
                        map2.put("techDeviceParamPicture", (techDeviceParam.getTechDeviceParamPicture() != null) ? techDeviceParam.getTechDeviceParamPicture() : "");
                        map2.put("type", 1);
                        if (pcbaDeviceRelatedTechParamActualByPcbaDeviceIdAndKey != null) {
                            map2.put("valueActual", pcbaDeviceRelatedTechParamActualByPcbaDeviceIdAndKey.getTechDeviceParamValue());
                            map2.put("valueActualAudit", pcbaDeviceRelatedTechParamActualByPcbaDeviceIdAndKey.getTechDeviceParamValueAudit());
                        } else {
                            map2.put("valueActual", "");
                            map2.put("valueActualAudit", "");
                        }
                        children.add(map2);
                    }

                }
                /*for (PcbaDeviceRelatedTechParam pcbaDeviceRelatedTechParam : pcbaDeviceRelatedTechParamList) {
                    TechDeviceParam techDeviceParam = techDeviceParamDao.getTechDeviceParamByKey(pcbaDeviceRelatedTechParam.getTechDeviceParamKey());
                    if(techDeviceParam != null && (techDeviceParam.getTechDeviceParamTypeId().equals(techDeviceParamType.getTechDeviceParamTypeId()))){
                        Map<String, Object> map2 = new HashMap<>();
                        map2.put("label", techDeviceParam.getTechDeviceParamNameCn());
                        map2.put("value", pcbaDeviceRelatedTechParam.getTechDeviceParamValue());
                        map2.put("key", pcbaDeviceRelatedTechParam.getTechDeviceParamKey());
                        map2.put("notes", (techDeviceParam.getNotes() != null) ? techDeviceParam.getNotes() : "");
                        map2.put("techDeviceParamPicture", (techDeviceParam.getTechDeviceParamPicture() != null) ?techDeviceParam.getTechDeviceParamPicture() : "");
                        map2.put("type", 1);
                        children.add(map2);
                    }
                }*/
                map1.put("label", techDeviceParamType.getTechDeviceParamTypeName());
                map1.put("value", techDeviceParamType.getTechDeviceParamTypeName());
                map1.put("children", children);

                /*for(Map.Entry<String, Object> entry : map1.entrySet()){
                    System.out.println(entry.getKey() + ":" + entry.getValue());
                    if("children".equals(entry.getKey())){
                        List<Map<String, Object>> children_ = (List<Map<String, Object>>) entry.getValue();
                        int index = 0;
                        for (Map<String, Object> stringObjectMap : children_) {
                            for (PcbaDeviceRelatedTechParamActual pcbaDeviceRelatedTechParamActual : pcbaDeviceRelatedTechParamActualList) {
                                if(stringObjectMap.get("key").toString().equals(pcbaDeviceRelatedTechParamActual.getTechDeviceParamKey())){
                                    children.get(index).put("valueActual", pcbaDeviceRelatedTechParamActual.getTechDeviceParamValue());
                                    index ++;
                                }
                            }
                        }
                    }
                }*/
                list.add(map1);
            }
            return ResultUtil.success(list);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @Override
    public Result getPcbaParamValue(Integer pcbaDeviceTypeId, Integer pcbaDeviceResourceId) {
        try {
            if (pcbaDeviceResourceId == null || "".equals(pcbaDeviceResourceId.toString())) {
                return ResultUtil.error(500, "缺少参数pcbaDeviceResourceId", "Miss Param pcbaDeviceResourceId", null);
            }
            if (pcbaDeviceTypeId == null || "".equals(pcbaDeviceTypeId.toString())) {
                return ResultUtil.error(500, "缺少参数pcbaDeviceTypeId", "Miss Param pcbaDeviceTypeId", null);
            }
            List<Map<String, Object>> list = new ArrayList<>();
            List<PcbaDeviceParamType> pcbaDeviceParamTypeList = pcbaDeviceParamTypeDao.getPcbaDeviceParamTypeByPcbaDeviceTypeId(pcbaDeviceTypeId, "");

            for (PcbaDeviceParamType pcbaDeviceParamType : pcbaDeviceParamTypeList) {
                Map<String, Object> map1 = new HashMap<>();
                List<Map<String, Object>> children = new ArrayList<>();
                List<PcbaDeviceParam> allPcbaDeviceParam = pcbaDeviceParamDao.getAllPcbaDeviceParam(pcbaDeviceTypeId, pcbaDeviceParamType.getPcbaDeviceParamTypeId(), null);
                for (PcbaDeviceParam pcbaDeviceParam : allPcbaDeviceParam) {
                    PcbaDeviceRelatedDeviceParam pcbaDeviceRelatedDeviceParam = pcbaDeviceRelatedDeviceParamDao.getPcbaDeviceRelatedDeviceParamByKeyAndDeviceResourceId(pcbaDeviceParam.getPcbaDeviceParamKey(), pcbaDeviceResourceId);
                    Map<String, Object> map2 = new HashMap<>();
                    map2.put("label", pcbaDeviceParam.getPcbaDeviceParamNameCn());
                    map2.put("value", pcbaDeviceRelatedDeviceParam != null ? pcbaDeviceRelatedDeviceParam.getPcbaDeviceParamValue() : "");
                    map2.put("key", pcbaDeviceParam.getPcbaDeviceParamKey());
                    map2.put("type", 1);
                    children.add(map2);
                }
                map1.put("label", pcbaDeviceParamType.getPcbaDeviceParamTypeName());
                map1.put("value", pcbaDeviceParamType.getPcbaDeviceParamTypeName());
                map1.put("children", children);
                list.add(map1);
            }

            // 根据 pcbaResourceId 查询
            /*List<PcbaDeviceRelatedDeviceParam> pcbaDeviceRelatedDeviceParamList = pcbaDeviceRelatedDeviceParamDao.getAllByDeviceResourceId(pcbaDeviceResourceId);

            List<Map<String, Object>> list = new ArrayList<>();
            for (PcbaDeviceParamType pcbaDeviceParamType : pcbaDeviceParamTypeList) {
                Map<String, Object> map1 = new HashMap<>();
                List<Map<String, Object>> children = new ArrayList<>();
                for (PcbaDeviceRelatedDeviceParam pcbaDeviceRelatedDeviceParam : pcbaDeviceRelatedDeviceParamList) {
                    PcbaDeviceParam pcbaDeviceParam = pcbaDeviceParamDao.getPcbaDeviceParamByKey(pcbaDeviceRelatedDeviceParam.getPcbaDeviceParamKey());
                    if(pcbaDeviceParam != null && (pcbaDeviceParam.getPcbaDeviceParamTypeId().equals(pcbaDeviceParamType.getPcbaDeviceParamTypeId()))){
                        Map<String, Object> map2 = new HashMap<>();
                        map2.put("label", pcbaDeviceParam.getPcbaDeviceParamNameCn());
                        map2.put("value", pcbaDeviceRelatedDeviceParam.getPcbaDeviceParamValue());
                        map2.put("key", pcbaDeviceRelatedDeviceParam.getPcbaDeviceParamKey());
                        map2.put("type", 1);
                        children.add(map2);
                    }
                }
                map1.put("label", pcbaDeviceParamType.getPcbaDeviceParamTypeName());
                map1.put("value", pcbaDeviceParamType.getPcbaDeviceParamTypeName());
                map1.put("children", children);

                list.add(map1);
            }*/
            return ResultUtil.success(list);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @Override
    public Result exportDeviceListExcel(String searchValue, Integer status, Integer pcbaCompanyId, Integer pcbaWorkshopId, Integer pcbaProcessId, Integer isFilledUpkeep) {
        try {
            List<Integer> companyIdList = strToCompanys.getPcbaCompanyIdListFromStr();
            String excelName = "设备保养计划";
            List<PcbaDevice> list = pcbaDeviceDao.getAllPcbaDevice(null, searchValue, status, null, null, pcbaCompanyId, pcbaWorkshopId, pcbaProcessId, isFilledUpkeep, companyIdList);
            for (PcbaDevice pcbaDevice : list) {
                PcbaDeviceResource pcbaDeviceResource = pcbaDeviceResourceDao.getById(pcbaDevice.getPcbaDeviceResourceId());
                pcbaDeviceResource.setBrand(brandDao.getBrandById(pcbaDeviceResource.getBrandId()));
                pcbaDeviceResource.setBrandType(brandTypeDao.getBrandTypeById(pcbaDeviceResource.getBrandTypeId()));
                pcbaDeviceResource.setPcbaDeviceType(pcbaDeviceTypeDao.getById(pcbaDeviceResource.getPcbaDeviceTypeId()));
                pcbaDevice.setPcbaDeviceResource(pcbaDeviceResource);

                pcbaDevice.setUpkeepList(upkeepDao.getUpkeepByDeviceId(pcbaDevice.getAssetNumber(), null));

                PcbaLine pcbaLine = pcbaLineDao.getPcbaLineById(pcbaDevice.getPcbaLineId());
                pcbaLine.setPcbaCompany(pcbaCompanyDao.getPcbaCompanyById(pcbaLine.getPcbaCompanyId()));
                pcbaLine.setPcbaWorkshop(pcbaWorkshopDao.getPcbaWorkshopById(pcbaLine.getPcbaWorkshopId()));
                pcbaLine.setPcbaProcess(pcbaProcessDao.getPcbaProcessById(pcbaLine.getPcbaProcessId()));
                pcbaDevice.setPcbaLine(pcbaLine);
            }

            // 创建工作簿对象
            Workbook workbook = new XSSFWorkbook();
            // 创建工作表对象
            Sheet sheet = workbook.createSheet(CommonUtils.handleSheetName(excelName));
            // 创建行和单元格对象
            Row row = sheet.createRow(0);

            CellStyle bodyContextCellStyle = workbook.createCellStyle();
            DataFormat format = workbook.createDataFormat();
            bodyContextCellStyle.setDataFormat(format.getFormat("@"));
            bodyContextCellStyle.setBorderBottom(BorderStyle.THIN);
            bodyContextCellStyle.setBorderLeft(BorderStyle.THIN);
            bodyContextCellStyle.setBorderRight(BorderStyle.THIN);
            bodyContextCellStyle.setBorderTop(BorderStyle.THIN);
            bodyContextCellStyle.setAlignment(HorizontalAlignment.LEFT);
            bodyContextCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

            CellStyle titleContextCellStyle = workbook.createCellStyle();
            titleContextCellStyle.setBorderBottom(BorderStyle.THIN);
            titleContextCellStyle.setBorderLeft(BorderStyle.THIN);
            titleContextCellStyle.setBorderRight(BorderStyle.THIN);
            titleContextCellStyle.setBorderTop(BorderStyle.THIN);
            // 设置背景色为红色
            titleContextCellStyle.setFillForegroundColor(IndexedColors.BLUE.getIndex());
            // 创建字体对象
            Font titleFont = workbook.createFont();
            // 设置字体颜色为蓝色
            titleFont.setColor(IndexedColors.WHITE.getIndex());
            titleFont.setBold(true);
            titleContextCellStyle.setFont(titleFont);
            // 设置填充类型为填充实体背景
            titleContextCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            List<Map<String, Object>> titleList = new ArrayList<>();
            //工厂名称、车间、线体/工序、设备种类、设备编号、品牌（自动关联）、型号（自动关联）、保养周期、
            // 保养计划（以电子流交互的方式实现保养计划的制定、修改、审批和过程监控）；
            // 关联到资产编号-唯一性（by工厂去管保养计划，只能看到工厂自己的）
            Map<String, Object> map = new HashMap<>();
            map = new HashMap<>();
            map.put("title", "工厂名称");
            map.put("width", 3000);
            titleList.add(map);
            map = new HashMap<>();
            map.put("title", "车间");
            map.put("width", 3000);
            titleList.add(map);
            map = new HashMap<>();
            map.put("title", "线体/工序");
            map.put("width", 3000);
            titleList.add(map);
            map = new HashMap<>();
            map.put("title", "设备种类");
            map.put("width", 3000);
            titleList.add(map);
            map = new HashMap<>();
            map.put("title", "资产编号");
            map.put("width", 3000);
            titleList.add(map);
            map = new HashMap<>();
            map.put("title", "品牌");
            map.put("width", 3000);
            titleList.add(map);
            map = new HashMap<>();
            map.put("title", "型号");
            map.put("width", 3000);
            titleList.add(map);
            map = new HashMap<>();
            map.put("title", "备注");
            map.put("width", 6000);
            titleList.add(map);
            map = new HashMap<>();
            map.put("title", "保养计划(单选：月度、季度、半年、年度)");
            map.put("width", 10000);
            titleList.add(map);
            map = new HashMap<>();
            map.put("title", "首次保养时间");
            map.put("width", 4000);
            titleList.add(map);
            map = new HashMap<>();
            map.put("title", "责任人");
            map.put("width", 3000);
            titleList.add(map);
            map = new HashMap<>();
            map.put("title", "联系方式");
            map.put("width", 3000);
            titleList.add(map);
            for (int a = 0; a < titleList.size(); a++) {
                sheet.setColumnWidth(a, Integer.parseInt(titleList.get(a).get("width").toString()));
                Cell cell = row.createCell(a);
                // 向单元格中写入数据
                cell.setCellValue(titleList.get(a).get("title").toString());
                cell.setCellStyle(titleContextCellStyle);
            }

            int dataBeginIndex = 1;
            int index = 0;// 序号
            // 渲染数据
            for (int b = 0; b < list.size(); b++) {
                List<Upkeep> upkeepList = list.get(b).getUpkeepList();

                if (upkeepList != null && upkeepList.size() > 0) {
                    for (int c = 0; c < upkeepList.size(); c++) {
                        index++;
                        Row row_ = sheet.createRow(index);
                        // 工厂名称
                        Cell cell_ = row_.createCell(0);
                        cell_.setCellValue(list.get(b).getPcbaLine().getPcbaCompany().getPcbaCompanyNameCn());
                        cell_.setCellStyle(bodyContextCellStyle);

                        // 车间
                        cell_ = row_.createCell(1);
                        cell_.setCellValue(list.get(b).getPcbaLine().getPcbaWorkshop().getPcbaWorkshopNameCn());
                        cell_.setCellStyle(bodyContextCellStyle);

                        // 线体/工序
                        cell_ = row_.createCell(2);
                        cell_.setCellValue(list.get(b).getPcbaLine().getPcbaProcess().getPcbaProcessNameCn());
                        cell_.setCellStyle(bodyContextCellStyle);

                        // 设备种类
                        cell_ = row_.createCell(3);
                        cell_.setCellValue(list.get(b).getPcbaDeviceResource().getPcbaDeviceType().getPcbaDeviceTypeNameCn());
                        cell_.setCellStyle(bodyContextCellStyle);

                        // 品牌
                        cell_ = row_.createCell(5);
                        cell_.setCellValue(list.get(b).getPcbaDeviceResource().getBrand().getBrandName());
                        cell_.setCellStyle(bodyContextCellStyle);

                        // 型号
                        cell_ = row_.createCell(6);
                        cell_.setCellValue(list.get(b).getPcbaDeviceResource().getBrandType().getBrandTypeName());
                        cell_.setCellStyle(bodyContextCellStyle);

                        // 备注
                        cell_ = row_.createCell(7);
                        cell_.setCellValue(list.get(b).getPcbaDeviceResource().getNotes());
                        cell_.setCellStyle(bodyContextCellStyle);

                        // 资产编号
                        cell_ = row_.createCell(4);
                        cell_.setCellValue(list.get(b).getAssetNumber());
                        cell_.setCellStyle(bodyContextCellStyle);

                        // 保养计划
                        cell_ = row_.createCell(8);
                        String type = "";
                        if (upkeepList.get(c).getUpkeepType() != null) {
                            if ("1".equals(upkeepList.get(c).getUpkeepType().toString())) {
                                type = "月度";
                            } else if ("2".equals(upkeepList.get(c).getUpkeepType().toString())) {
                                type = "季度";
                            } else if ("3".equals(upkeepList.get(c).getUpkeepType().toString())) {
                                type = "半年";
                            } else if ("4".equals(upkeepList.get(c).getUpkeepType().toString())) {
                                type = "年度";
                            }
                            cell_.setCellValue(type);
                            cell_.setCellStyle(bodyContextCellStyle);
                        }

                        // 首次保养时间
                        cell_ = row_.createCell(9);
                        if (upkeepList.get(c).getFirstUpkeepTime() != null) {
                            DateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
                            String strdate = dateformat.format(upkeepList.get(c).getFirstUpkeepTime());
                            cell_.setCellValue(strdate);
                            cell_.setCellStyle(bodyContextCellStyle);
                        }

                        // 责任人
                        cell_ = row_.createCell(10);
                        cell_.setCellValue(upkeepList.get(c).getOwnerId() != null ? upkeepList.get(c).getOwnerId().toString() : "");
                        cell_.setCellStyle(bodyContextCellStyle);

                        // 联系方式
                        cell_ = row_.createCell(11);
                        cell_.setCellValue(upkeepList.get(c).getContactMethod() != null ? upkeepList.get(c).getContactMethod() : "");
                        cell_.setCellStyle(bodyContextCellStyle);

                    }
                    // 合并单元格
                    //System.out.println("dataBeginIndex==" + dataBeginIndex);
                    //System.out.println("index==" + index);
                    if (upkeepList.size() > 1) {
                        if (index > dataBeginIndex) {
                            sheet.addMergedRegion(new CellRangeAddress(dataBeginIndex, index, 0, 0));
                            sheet.addMergedRegion(new CellRangeAddress(dataBeginIndex, index, 1, 1));
                            sheet.addMergedRegion(new CellRangeAddress(dataBeginIndex, index, 2, 2));
                            sheet.addMergedRegion(new CellRangeAddress(dataBeginIndex, index, 3, 3));
                            sheet.addMergedRegion(new CellRangeAddress(dataBeginIndex, index, 5, 5));
                            sheet.addMergedRegion(new CellRangeAddress(dataBeginIndex, index, 6, 6));
                            sheet.addMergedRegion(new CellRangeAddress(dataBeginIndex, index, 7, 7));
                            dataBeginIndex = index + 1;
                        }
                    } else {
                        dataBeginIndex = index + 1;
                    }
                } else {
                    index++;
                    Row row_ = sheet.createRow(index);
                    // 工厂名称
                    Cell cell_ = row_.createCell(0);
                    cell_.setCellValue(list.get(b).getPcbaLine().getPcbaCompany().getPcbaCompanyNameCn());
                    cell_.setCellStyle(bodyContextCellStyle);

                    // 车间
                    cell_ = row_.createCell(1);
                    cell_.setCellValue(list.get(b).getPcbaLine().getPcbaWorkshop().getPcbaWorkshopNameCn());
                    cell_.setCellStyle(bodyContextCellStyle);

                    // 线体/工序
                    cell_ = row_.createCell(2);
                    cell_.setCellValue(list.get(b).getPcbaLine().getPcbaProcess().getPcbaProcessNameCn());
                    cell_.setCellStyle(bodyContextCellStyle);

                    // 设备种类
                    cell_ = row_.createCell(3);
                    cell_.setCellValue(list.get(b).getPcbaDeviceResource().getPcbaDeviceType().getPcbaDeviceTypeNameCn());
                    cell_.setCellStyle(bodyContextCellStyle);

                    // 品牌
                    cell_ = row_.createCell(5);
                    cell_.setCellValue(list.get(b).getPcbaDeviceResource().getBrand().getBrandName());
                    cell_.setCellStyle(bodyContextCellStyle);

                    // 型号
                    cell_ = row_.createCell(6);
                    cell_.setCellValue(list.get(b).getPcbaDeviceResource().getBrandType().getBrandTypeName());
                    cell_.setCellStyle(bodyContextCellStyle);

                    // 备注
                    cell_ = row_.createCell(7);
                    cell_.setCellValue(list.get(b).getPcbaDeviceResource().getNotes());
                    cell_.setCellStyle(bodyContextCellStyle);

                    // 资产编号
                    cell_ = row_.createCell(4);
                    cell_.setCellValue(list.get(b).getAssetNumber());
                    cell_.setCellStyle(bodyContextCellStyle);
                }
            }

            String fileName = excelName + CommonUtils.getTimestamp() + ".xlsx";
            String pathPrefix = fileSaveUrl + "exportExcels\\";
            File folder = new File(pathPrefix);
            if (!folder.isDirectory()) {
                folder.mkdirs();
            }
            String filePath = pathPrefix + fileName;
            // 导出Excel文件
            FileOutputStream outputStream = new FileOutputStream(filePath);
            workbook.write(outputStream);
            workbook.close();
            outputStream.close();

            byte[] data = null;
            InputStream in = new FileInputStream(filePath);
            data = new byte[in.available()];
            in.read(data);
            in.close();
            java.util.Base64.Encoder encoder = java.util.Base64.getEncoder();
            String base64 = encoder.encodeToString(data);

            Map<String, Object> resMap = new HashMap<>();
            resMap.put("base64", base64);
            resMap.put("fileName", fileName);
            return ResultUtil.success(resMap);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @Transactional(transactionManager = "MysqlTransactionManager1")
    @Override
    public Result importDeviceUpkeepListExcel(MultipartFile file) {
        try {
            if (file == null) {
                return ResultUtil.error(500, "缺少参数file", "Miss Param file", null);
            }
            List<Map<String, Object>> list = new ArrayList<>();
            // 1.得到一个输入流对象
            //FileInputStream in = FileConverterUtils.convertTo(file);
            InputStream inputStream = file.getInputStream();
            File f = FileConverterUtils.getTempFileFromInputStream(inputStream);
            // 2.将输入流对象进行解析 得到workbook对象
            //Workbook workbook = new XSSFWorkbook(in);
            Workbook workbook = WorkbookFactory.create(f);
            // 3.workbook中有几个工作簿
            int sheetNum = workbook.getNumberOfSheets();
            System.out.println("一共有" + sheetNum + "个工作簿");
            // 3.1通过workbook 创建工作簿对象
            //Sheet sheet1 = workbook.getSheetAt(0);
            //Sheet sheet2 = workbook.getSheetAt(1);
            Sheet sheet = workbook.getSheetAt(0);
            int allRows = sheet.getLastRowNum() + 1;
            String sheetName = sheet.getSheetName();
            System.out.println("当前sheetName：" + sheetName);
            List<Map<String, Object>> list2 = new ArrayList<>();
            //判断sheetName在不在设备列表里面
            Row row = sheet.getRow(0);
            String t1 = row.getCell(0) != null ? row.getCell(0).toString() : "";
            String t2 = row.getCell(1) != null ? row.getCell(1).toString() : "";
            String t3 = row.getCell(2) != null ? row.getCell(2).toString() : "";
            String t4 = row.getCell(3) != null ? row.getCell(3).toString() : "";
            String t5 = row.getCell(4) != null ? row.getCell(4).toString() : "";
            String t6 = row.getCell(5) != null ? row.getCell(5).toString() : "";
            String t7 = row.getCell(6) != null ? row.getCell(6).toString() : "";
            String t8 = row.getCell(7) != null ? row.getCell(7).toString() : "";
            String t9 = row.getCell(8) != null ? row.getCell(8).toString() : "";
            String t10 = row.getCell(9) != null ? row.getCell(9).toString() : "";
            String t11 = row.getCell(10) != null ? row.getCell(10).toString() : "";
            String t12 = row.getCell(11) != null ? row.getCell(11).toString() : "";
            DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            if (t1.contains("工厂名称") && t2.contains("车间") && t3.contains("线体/工序") && t4.contains("设备种类") && t5.contains("资产编号") && t6.contains("品牌") && t7.contains("型号") && t8.contains("备注") && t9.contains("保养计划") && t10.contains("首次保养时间") && t11.contains("责任人") && t12.contains("联系方式")) {
                // 表头符合的，循环获取每行数据
                for (int b = 1; b < allRows; b++) {
                    Map<String, Object> map2 = new HashMap<>();
                    Row rowV = sheet.getRow(b);

                    // 获取合并单元格的数量
                    int mergedRegions = sheet.getNumMergedRegions();
                    String mergedCellValue1 = "";
                    for (int i = 0; i < mergedRegions; i++) {
                        CellRangeAddress cellRangeAddress = sheet.getMergedRegion(i);
                        int firstRow = cellRangeAddress.getFirstRow();
                        int lastRow = cellRangeAddress.getLastRow();
                        int firstCol = cellRangeAddress.getFirstColumn();
                        int lastCol = cellRangeAddress.getLastColumn();
                        if (b >= firstRow && b <= lastRow && firstCol == 4 && lastCol == 4) {
                            Cell cell = sheet.getRow(firstRow).getCell(4);
                            mergedCellValue1 = cell.getStringCellValue();
                            break;
                        }
                    }

                    String v5 = rowV.getCell(4) != null && !"".equals(rowV.getCell(4).toString()) ? rowV.getCell(4).toString() : mergedCellValue1;

                    String v9 = rowV.getCell(8) != null ? rowV.getCell(8).toString() : "";
                    String v10 = "";
                    if (rowV.getCell(9) != null && rowV.getCell(9).getCellType() == CellType.NUMERIC) {
                        double numericValue = rowV.getCell(9).getNumericCellValue();
                        // 将数字转换为Java日期/时间类型
                        Date date = DateUtil.getJavaDate(numericValue);
                        // 进一步处理日期/时间
                        String strdate = format.format(date);
                        v10 = strdate;
                    } else {
                        v10 = rowV.getCell(9) != null ? rowV.getCell(9).toString() : "";
                    }

                    String v11 = rowV.getCell(10) != null ? rowV.getCell(10).toString() : "";
                    String v12 = rowV.getCell(11) != null ? rowV.getCell(11).toString() : "";
                    map2.put("assetNumber", v5);
                    map2.put("upkeepType", v9);
                    map2.put("firstUpkeepTime", v10);
                    map2.put("ownerName", v11);
                    map2.put("contactMethod", v12);
                    list2.add(map2);
                }
            } else {
                return ResultUtil.error(500, "模板错误", "Template Error", null);
            }

            Map<String, Object> resMap = new HashMap<>();
            int successAddNum = 0;
            int successUpdateNum = 0;
            int failNum = 0;
            List<String> failList = new ArrayList<>();
            // 拿到 list2 循环存储到数据库 如果存在保养计划则覆盖
            for (int a = 0; a < list2.size(); a++) {
                Integer upkeepType = null;
                // 月度、季度、半年、年度
                if ("月度".equals(list2.get(a).get("upkeepType").toString())) {
                    upkeepType = 1;
                } else if ("季度".equals(list2.get(a).get("upkeepType").toString())) {
                    upkeepType = 2;
                } else if ("半年".equals(list2.get(a).get("upkeepType").toString())) {
                    upkeepType = 3;
                } else if ("年度".equals(list2.get(a).get("upkeepType").toString())) {
                    upkeepType = 4;
                }

                if (upkeepType != null) {
                    if (!"".equals(list2.get(a).get("assetNumber"))) {
                        Date firstUpkeepTime = null;
                        List<UpkeepAudit> upkeepAuditList = upkeepAuditDao.getUpkeepAuditByDeviceId(list2.get(a).get("assetNumber").toString(), upkeepType, null);
                        if (upkeepAuditList.size() == 0) {
                            // 插入
                            // 根据资产查询设备id
                            PcbaDevice p = pcbaDeviceDao.getByAssetNumber(list2.get(a).get("assetNumber").toString());
                            if (p != null) {
                                try {
                                    String time = list2.get(a).get("firstUpkeepTime").toString();
                                    if (!"".equals(time)) {
                                        firstUpkeepTime = format.parse(time);

                                        String assetNumber = list2.get(a).get("assetNumber").toString();
                                        String contactMethod = list2.get(a).get("contactMethod").toString();
                                        String ownerName = list2.get(a).get("ownerName").toString();

                                        if (ownerName == null || contactMethod == null || "".equals(ownerName) || "".equals(contactMethod)) {
                                            failList.add("第" + (a + 2) + "行数据【缺少信息】，可能缺少责任人或联系方式");
                                            failNum++;
                                        } else {
                                            UpkeepAudit addUpkeepAudit = new UpkeepAudit();
                                            addUpkeepAudit.setAssetNumber(assetNumber);
                                            addUpkeepAudit.setContactMethod(contactMethod);
                                            addUpkeepAudit.setUpkeepType(upkeepType);
                                            addUpkeepAudit.setCreateTime(new Date());
                                            addUpkeepAudit.setOwnerName(ownerName);
                                            addUpkeepAudit.setFirstUpkeepTime(firstUpkeepTime);
                                            addUpkeepAudit.setPcbaDeviceId(p.getPcbaDeviceId());
                                            addUpkeepAudit.setIsDelete(2);
                                            addUpkeepAudit.setUpkeepStatus(3);
                                            upkeepAuditDao.addUpkeepAudit(addUpkeepAudit);

                                            successAddNum++;
                                        }
                                    } else {
                                        failList.add("第" + (a + 2) + "行数据【首次保养时间】错误，可能格式不正确");
                                        failNum++;
                                    }

                                } catch (Exception e) {
                                    failList.add("第" + (a + 2) + "行数据【首次保养时间】错误，可能格式不正确");
                                    failNum++;
                                }
                            } else {
                                failList.add("第" + (a + 2) + "行数据【资产编号】错误，不存在对应设备");
                                failNum++;
                            }
                        } else {
                            // 更新
                            try {
                                String time = list2.get(a).get("firstUpkeepTime").toString();
                                if (!"".equals(time)) {
                                    firstUpkeepTime = format.parse(time);

                                    String assetNumber = list2.get(a).get("assetNumber").toString();
                                    String contactMethod = list2.get(a).get("contactMethod").toString();
                                    String ownerName = list2.get(a).get("ownerName").toString();
                                    UpkeepAudit updateUpkeepAudit = new UpkeepAudit();
                                    updateUpkeepAudit.setUpdateTime(new Date());
                                    updateUpkeepAudit.setAssetNumber(assetNumber);
                                    updateUpkeepAudit.setContactMethod(contactMethod);
                                    updateUpkeepAudit.setUpkeepType(upkeepType);
                                    updateUpkeepAudit.setFirstUpkeepTime(firstUpkeepTime);
                                    updateUpkeepAudit.setIsDelete(2);
                                    updateUpkeepAudit.setUpkeepId(upkeepAuditList.get(0).getUpkeepId());
                                    if (ownerName == null || contactMethod == null || "".equals(ownerName) || "".equals(contactMethod)) {
                                        failList.add("第" + (a + 2) + "行数据【缺少信息】，可能缺少责任人或联系方式");
                                        failNum++;
                                    } else {
                                        if (upkeepAuditList.get(0).getIsDelete() == 1) {
                                            // 假删除的需要恢复
                                            updateUpkeepAudit.setOwnerName(ownerName);
                                            updateUpkeepAudit.setContactMethod(contactMethod);
                                            updateUpkeepAudit.setUpkeepStatus(3); // 资料齐全直接 审核中
                                            upkeepAuditDao.updateUpkeepAudit(updateUpkeepAudit);
                                            successAddNum++;
                                        } else {
                                            // 更新的不再处理
                                        }
                                    }
                                } else {
                                    failList.add("第" + (a + 2) + "行数据【首次保养时间】错误，可能格式不正确");
                                    failNum++;
                                }
                            } catch (Exception e) {
                                failList.add("第" + (a + 2) + "行数据【首次保养时间】错误，可能格式不正确");
                                failNum++;
                            }
                        }
                    } else {
                        failList.add("第" + (a + 2) + "行数据【资产编号】错误");
                        failNum++;
                    }
                } else {
                    failList.add("第" + (a + 2) + "行数据【保养计划】错误");
                    failNum++;
                }
            }

            resMap.put("list2", list2);
            resMap.put("successAddNum", successAddNum);
            resMap.put("successUpdateNum", successUpdateNum);
            resMap.put("failNum", failNum);
            resMap.put("failList", failList);
            return ResultUtil.success(resMap);
            //return ResultUtil.success(list2);
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @Override
    public Result auditPcbaDevice(String paramsNotes, Integer pcbaDeviceId, Integer paramsStatus) {
        try {
            if (paramsStatus == null || "".equals(paramsStatus.toString())) {
                return ResultUtil.error(500, "缺少参数paramsStatus", "Miss Param paramsStatus", null);
            }
            if (pcbaDeviceId == null || "".equals(pcbaDeviceId.toString())) {
                return ResultUtil.error(500, "缺少参数pcbaDeviceId", "Miss Param pcbaDeviceId", null);
            }
            Boolean fl = false;
            String userId = UserHeaderHolder.getUserId();
            PcbaDevice oldPcbaDevice = pcbaDeviceDao.getById(pcbaDeviceId);
            Date d = new Date();
            Integer integer = pcbaDeviceDao.auditPcbaDevice(1, paramsNotes, pcbaDeviceId, paramsStatus, d);
            if (integer > 0) {

                if (paramsStatus == 1) {
                    Integer pcbaLineId = oldPcbaDevice.getPcbaLineId();
                    PcbaLine pcbaLineById = pcbaLineDao.getPcbaLineById(pcbaLineId);
                    /*// 审核通过，将 valueAudit 的值清空
                    pcbaDeviceRelatedTechParamActualDao.clearValueAudit(pcbaDeviceId);*/
                    // 审核通过，将
                    pcbaDeviceRelatedTechParamActualDao.returnValueAuditFromValue(pcbaDeviceId);

                    // 审核通过 额外新增判断
                    // 判断一下该线体下的所有设备是否 存在 超期 状态，如果存在设备超期状态，则将线体的工艺实际能力认证状态改为 存在设备超期6
                    // 如果不存在设备超期，则统一将 线体的工艺实际能力认证状态改为 待提交认证4
                    List<PcbaDevice> pcbaDeviceList = pcbaDeviceDao.getPcbaDeviceByLine(oldPcbaDevice.getPcbaLineId());
                    Boolean isHasOverDue = false;
                    for (PcbaDevice pcbaDevice : pcbaDeviceList) {
                        if (pcbaDevice.getParamsStatus() == 5) {
                            isHasOverDue = true;
                            break;
                        }
                    }

                    // 只有当原先线体的实际工艺能力状态为 6 的时候（线体下存在设备超期），才触发以下逻辑
                    if(pcbaLineById.getParamsStatusActual() == 6){
                        if (isHasOverDue) {
                            pcbaLineDao.auditPcbaLineTechActual("", oldPcbaDevice.getPcbaLineId(), 6, new Date());
                        } else {
                            pcbaLineDao.auditPcbaLineTechActual("", oldPcbaDevice.getPcbaLineId(), 4, new Date());
                        }
                    }
                }
                if (paramsStatus == 2) {
                    // 审核不通过，将 value 的值还原成 valueAudit 的值
                    pcbaDeviceRelatedTechParamActualDao.returnValueFromValueAudit(pcbaDeviceId);
                }

                PcbaDevice newPcbaDevice = new PcbaDevice();
                newPcbaDevice.setPcbaDeviceId(pcbaDeviceId);
                newPcbaDevice.setParamsStatus(paramsStatus);
                newPcbaDevice.setUpdateTime(d);
                newPcbaDevice.setParamsNotes(paramsNotes);
                // 添加操作日志
                operateService.addOperate(new Operate(1, Integer.parseInt(userId), operateSmallType, 3, 1, d, JSONObject.toJSONString(oldPcbaDevice), JSONObject.toJSONString(newPcbaDevice)));

                // 添加 审核记录
//                AuditHistory addAuditHistory = new AuditHistory();
//                addAuditHistory.setAuditType(1);
//                addAuditHistory.setCreateTime(d);
//                addAuditHistory.setSubmitUserId(null);
//                addAuditHistory.setAuditUserId(Integer.parseInt(userId));
//                addAuditHistory.setAuditStatus(paramsStatus);
//                addAuditHistory.setAuditNotes(paramsNotes);
//                addAuditHistory.setRelatedId(pcbaDeviceId);
//                auditHistoryDao.addAuditHistory(addAuditHistory);

                //发送邮件
                /*try{
                    List<User> userList = new ArrayList<>();
                    Integer pcbaLineId = oldPcbaDevice.getPcbaLineId();
                    if(pcbaLineId != null){
                        PcbaLine pcbaLine = pcbaLineDao.getPcbaLineById(pcbaLineId);
                        if(pcbaLine != null){
                            PcbaCompany pcbaCompany = pcbaCompanyDao.getPcbaCompanyById(pcbaLine.getPcbaCompanyId());
                            if(pcbaCompany != null){
                                String emailOwners5 = pcbaCompany.getEmailOwners5();
                                if(emailOwners5 != null && !"".equals(emailOwners5)){
                                    String[] split = emailOwners5.split(",");
                                    for (String s : split) {
                                        if(s.contains("/")){
                                            String[] strings = s.split("\\/");
                                            if(strings.length == 2){
                                                String domainAccount = strings[1];
                                                if(domainAccount != null && !"".equals(domainAccount)){
                                                    User u = userDao.getUserInfoByDomainAccount(domainAccount);
                                                    if(u != null){
                                                        userList.add(u);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    List<MailAddress> mailAddressList = new ArrayList<>();
                    for (User user : userList) {
                        MailAddress mailAddress = new MailAddress();
                        mailAddress.setMailAddress(user.getEmail());
                        mailAddress.setType(0);
                        mailAddressList.add(mailAddress);
                    }

                    if(mailAddressList.size() > 0){
                        if(paramsStatus == 1){
                            Result result = thirdApiService.sendMail("", DB1EmailTemplates.DEVICE_TECH_PARAMS_TITLE_OK, DB1EmailTemplates.DEVICE_TECH_PARAMS_MAIL_CONTENT_TITLE_OK,
                                    DB1EmailTemplates.DEVICE_TECH_PARAMS_MAIL_CONTENT_OK, "10086", mailAddressList, null, null, null, null, 2, null);
                            if(result.getCode() == 200){
                                System.out.println(CommonUtils.formatCurrentTime() + "==========================================");
                                System.out.println("设备实际工艺能力审核结果邮件,发送成功");
                            }else{
                                System.out.println(CommonUtils.formatCurrentTime() + "==========================================");
                                System.out.println("设备实际工艺能力审核结果邮件,发送失败:" + result.getMsgCn());
                            }
                        }else if(paramsStatus == 2){
                            Result result = thirdApiService.sendMail("", DB1EmailTemplates.DEVICE_TECH_PARAMS_TITLE_NO, DB1EmailTemplates.DEVICE_TECH_PARAMS_MAIL_CONTENT_TITLE_NO,
                                    DB1EmailTemplates.DEVICE_TECH_PARAMS_MAIL_CONTENT_NO, "10086", mailAddressList, null, null, null, null, 2, null);
                            if(result.getCode() == 200){
                                System.out.println(CommonUtils.formatCurrentTime() + "==========================================");
                                System.out.println("设备实际工艺能力审核结果邮件,发送成功");
                            }else{
                                System.out.println(CommonUtils.formatCurrentTime() + "==========================================");
                                System.out.println("设备实际工艺能力审核结果邮件,发送失败:" + result.getMsgCn());
                            }
                        }
                    }
                }catch (Exception e){
                    e.printStackTrace();
                    System.out.println(CommonUtils.formatCurrentTime() + "==========================================");
                    System.out.println("设备实际工艺能力审核结果邮件发送失败：" + e.getMessage());
                }*/

                // 非SMT线体需要判断 该设备所在的线体下的所有设备是否 工艺实际能力都认证通过，当都认证通过，则需要将线体的工艺实际认证能力也改为1
                if (paramsStatus == 1) {
                    Integer pcbaLineId = oldPcbaDevice.getPcbaLineId();
                    PcbaLine pcbaLineById = pcbaLineDao.getPcbaLineById(pcbaLineId);
                    if (pcbaLineById != null) {
                        Integer pcbaLineType = pcbaLineById.getPcbaLineType();
                        if (pcbaLineType != 1) {
                            List<PcbaDevice> pcbaDeviceByLine = pcbaDeviceDao.getPcbaDeviceByLine(pcbaLineId);
                            Boolean b = true;
                            for (PcbaDevice pcbaDevice : pcbaDeviceByLine) {
                                if (!pcbaDevice.getPcbaDeviceId().equals(pcbaDeviceId)) {
                                    Integer isFilledTechParamsActual = pcbaDevice.getIsFilledTechParamsActual();
                                    if (isFilledTechParamsActual != 1) {
                                        b = false;
                                        break;
                                    }
                                }
                            }
                            if (b) {
                                // 修改线体的工艺实际认证能力也改为1
                                PcbaLine upPcbaline = new PcbaLine();
                                upPcbaline.setPcbaLineId(pcbaLineId);
                                upPcbaline.setParamsStatusActual(1);
                                pcbaLineDao.updatePcbaLine(upPcbaline);
                                fl = true;
                            }
                        }
                    }
                }

                // 级联触发 线体的最终状态
                coreAlgorithmService.cascadeUpdateLineFinalStatus(2, null, pcbaDeviceId, null);
                return ResultUtil.success(fl);
            }
            return ResultUtil.error(500, "操作失败", "Operate Fail", null);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @Override
    public Result autoAuditDeviceAndLineWithoutTechParam(Integer pcbaDeviceId) {
        try {
            if (pcbaDeviceId == null || "".equals(pcbaDeviceId.toString())) {
                return ResultUtil.error(500, "缺少参数pcbaDeviceId", "Miss Param pcbaDeviceId", null);
            }
            PcbaDevice pd = pcbaDeviceDao.getById(pcbaDeviceId);
            if (pd != null) {
                Integer pcbaDeviceTypeId = pd.getPcbaDeviceTypeId();
                Integer pcbaLineId = pd.getPcbaLineId();
                List<TechDeviceParam> allTechDeviceParam = techDeviceParamDao.getAllTechDeviceParam(pcbaDeviceTypeId, null, null);
                if (allTechDeviceParam.size() == 0) {
                    // 将设备的工艺认证状态变为 1
                    pcbaDeviceDao.auditPcbaDevice(1, null, pcbaDeviceId, 1, new Date());

                    // 判断该线体下所有设备的实际工艺能力是否都认证通过， 如果都认证通过，则将设备所在的线体的工艺认证状态变为 1，否则变为2
                    Boolean isAllPass = true;
                    List<PcbaDevice> pcbaDeviceByLine = pcbaDeviceDao.getPcbaDeviceByLine(pcbaLineId);
                    for (PcbaDevice pcbaDevice : pcbaDeviceByLine) {
                        if (pcbaDevice.getParamsStatus() == null || pcbaDevice.getParamsStatus() != 1) {
                            isAllPass = false;
                            break;
                        }
                    }
                    if (pcbaLineId != null) {
                        PcbaLine pcbaLineById = pcbaLineDao.getPcbaLineById(pcbaLineId);
                        // 4：待提交审核
                        if(pcbaLineById != null && pcbaLineById.getParamsStatusActual() != 4){
                            if (isAllPass) {
                                pcbaLineDao.auditPcbaLineTechActual(null, pcbaLineId, 1, new Date());
                            } else {
                                pcbaLineDao.auditPcbaLineTechActual(null, pcbaLineId, 2, new Date());
                            }
                        }
                    }
                    // 同时需要级联触发线体的 finalStatus
                    coreAlgorithmService.cascadeUpdateLineFinalStatus(3, null, null, pcbaLineId);
                }
            }
            return ResultUtil.success(null);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @Transactional(transactionManager = "MysqlTransactionManager1")
    @Override
    public Result handleHighLoopClose(Integer pcbaDeviceId, Integer loopCloseStatus, String loopCloseAuditReason) {
        try {
            if (pcbaDeviceId == null || "".equals(pcbaDeviceId.toString())) {
                return ResultUtil.error(500, "缺少参数pcbaDeviceId", "Miss param pcbaDeviceId", null);
            }
            if (loopCloseStatus == null || "".equals(loopCloseStatus.toString())) {
                return ResultUtil.error(500, "缺少参数loopCloseStatus", "Miss param loopCloseStatus", null);
            }

            PcbaDevice pcbaDevice = pcbaDeviceDao.getById(pcbaDeviceId);

            Date d = new Date();
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(d);
            calendar.set(Calendar.HOUR_OF_DAY, 0); // 设置小时为 0
            calendar.set(Calendar.MINUTE, 0);      // 设置分钟为 0
            calendar.set(Calendar.SECOND, 0);      // 设置秒钟为 0
            calendar.set(Calendar.MILLISECOND, 0); // 设置毫秒为 0
            Date time = calendar.getTime();
            String userId = UserHeaderHolder.getUserId();

            if(loopCloseStatus == 1){
                Integer integer = pcbaDeviceDao.handleHighLoopCloseOk(pcbaDeviceId, loopCloseStatus, Integer.parseInt(userId), time, loopCloseAuditReason);
                if (integer > 0) {

                    /*DeviceAgeHistory addDeviceAgeHistory = new DeviceAgeHistory();
                    addDeviceAgeHistory.setAuditorId(Integer.parseInt(userId));
                    addDeviceAgeHistory.setAuditStatus(loopCloseStatus);
                    addDeviceAgeHistory.setCreateTime(new Date());
                    addDeviceAgeHistory.setPcbaDeviceId(pcbaDeviceId);
                    addDeviceAgeHistory.setCloseAuditReason(loopCloseAuditReason);
                    addDeviceAgeHistory.setType(1);
                    deviceAgeHistoryDao.addDeviceAgeHistory(addDeviceAgeHistory);*/
                    // 不能新增历史记录，需要根据流程uuid update
                    List<DeviceAgeHistory> deviceAgeHistories = deviceAgeHistoryDao.getByTypeAndUuid(1, pcbaDevice.getLoopCloseUuid());
                    for (DeviceAgeHistory deviceAgeHistory : deviceAgeHistories) {
                        deviceAgeHistory.setUpdateTime(d);
                        deviceAgeHistory.setCloseAuditReason(loopCloseAuditReason);
                        deviceAgeHistory.setAuditStatus(loopCloseStatus);
                        deviceAgeHistory.setAuditorId(Integer.parseInt(userId));
                        deviceAgeHistoryDao.updateDeviceAgeHistory(deviceAgeHistory);
                    }

                    /*1：挂起审核通过
                    2：挂起审核中
                    3：挂起审核拒绝
                    4：关闭审核通过
                    5：关闭审核中
                    6：关闭审核拒绝*/
                    // 审核通过 ，需要查询 loopCloseMethod 的值，
                    // 如果 loopCloseMethod = 1，修改 tb_pcba_device_age_handled 的 loop_handled_status 的状态 = 1(挂起审核通过)
                    // 如果 loopCloseMethod = 2，修改 tb_pcba_device_age_handled 的 loop_handled_status 的状态 = 4(关闭审核通过)
                    PcbaDeviceAgeHandled pcbaDeviceAgeHandled = pcbaDeviceAgeHandledDao.getById(pcbaDeviceId);
                    if(pcbaDeviceAgeHandled != null){
                        pcbaDeviceAgeHandled.setLoopHandledStatus(
                                pcbaDevice.getAgeCloseMethod() != null && pcbaDevice.getLoopCloseMethod().equals(1) ? 1 : 4
                        );
                        //pcbaDeviceAgeHandled.setLoopHandledStatus(pcbaDevice.getLoopCloseMethod() != null ? (pcbaDevice.getLoopCloseMethod() == 1 ? 1 : 4) : 1);
                        pcbaDeviceAgeHandledDao.updatePcbaDeviceAgeHandled(pcbaDeviceAgeHandled);
                    }
                }
            }else{
                Integer integer = pcbaDeviceDao.handleHighLoopCloseNo(pcbaDeviceId, loopCloseStatus, loopCloseAuditReason);
                if (integer > 0) {
                    /*DeviceAgeHistory addDeviceAgeHistory = new DeviceAgeHistory();
                    addDeviceAgeHistory.setAuditorId(Integer.parseInt(userId));
                    addDeviceAgeHistory.setAuditStatus(loopCloseStatus);
                    addDeviceAgeHistory.setCreateTime(new Date());
                    addDeviceAgeHistory.setPcbaDeviceId(pcbaDeviceId);
                    addDeviceAgeHistory.setCloseAuditReason(loopCloseAuditReason);
                    addDeviceAgeHistory.setType(1);
                    deviceAgeHistoryDao.addDeviceAgeHistory(addDeviceAgeHistory);*/
                    // 不能新增历史记录，需要根据流程uuid update
                    List<DeviceAgeHistory> deviceAgeHistories = deviceAgeHistoryDao.getByTypeAndUuid(1, pcbaDevice.getLoopCloseUuid());
                    for (DeviceAgeHistory deviceAgeHistory : deviceAgeHistories) {
                        deviceAgeHistory.setUpdateTime(d);
                        deviceAgeHistory.setCloseAuditReason(loopCloseAuditReason);
                        deviceAgeHistory.setAuditStatus(loopCloseStatus);
                        deviceAgeHistory.setAuditorId(Integer.parseInt(userId));
                        deviceAgeHistoryDao.updateDeviceAgeHistory(deviceAgeHistory);
                    }

                    /*1：挂起审核通过
                    2：挂起审核中
                    3：挂起审核拒绝
                    4：关闭审核通过
                    5：关闭审核中
                    6：关闭审核拒绝*/
                    // 审核不通过 ，需要查询 loopCloseMethod 的值，
                    // 如果 loopCloseMethod = 1，修改 tb_pcba_device_age_handled 的 loop_handled_status 的状态 = 3(挂起审核拒绝)
                    // 如果 loopCloseMethod = 2，修改 tb_pcba_device_age_handled 的 loop_handled_status 的状态 = 6(关闭审核拒绝)
                    PcbaDeviceAgeHandled pcbaDeviceAgeHandled = pcbaDeviceAgeHandledDao.getById(pcbaDeviceId);
                    if(pcbaDeviceAgeHandled != null){
                        Integer method = pcbaDevice.getLoopCloseMethod();
                        pcbaDeviceAgeHandled.setLoopHandledStatus(
                                method != null && !method.equals(1) ? 6 : 3
                        );
                        //pcbaDeviceAgeHandled.setLoopHandledStatus(pcbaDevice.getLoopCloseMethod() != null ? (pcbaDevice.getLoopCloseMethod() == 1 ? 3 : 6) : 3);
                        pcbaDeviceAgeHandledDao.updatePcbaDeviceAgeHandled(pcbaDeviceAgeHandled);
                    }
                }
            }
            return ResultUtil.success(null);
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @Transactional(transactionManager = "MysqlTransactionManager1")
    @Override
    public Result handleAgeLoopClose(Integer pcbaDeviceId, Integer ageCloseStatus, String ageCloseAuditReason) {
        try {
            if (pcbaDeviceId == null || "".equals(pcbaDeviceId.toString())) {
                return ResultUtil.error(500, "缺少参数pcbaDeviceId", "Miss param pcbaDeviceId", null);
            }
            if (ageCloseStatus == null || "".equals(ageCloseStatus.toString())) {
                return ResultUtil.error(500, "缺少参数ageCloseStatus", "Miss param ageCloseStatus", null);
            }
            Date d = new Date();
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(d);
            calendar.set(Calendar.HOUR_OF_DAY, 0); // 设置小时为 0
            calendar.set(Calendar.MINUTE, 0);      // 设置分钟为 0
            calendar.set(Calendar.SECOND, 0);      // 设置秒钟为 0
            calendar.set(Calendar.MILLISECOND, 0); // 设置毫秒为 0
            Date time = calendar.getTime();
            String userId = UserHeaderHolder.getUserId();

            List<MaintenanceConfig> maintenanceConfigList = maintenanceConfigDao.getMaintenanceConfigByType(1);
            if (maintenanceConfigList.size() == 3) {
                MaintenanceConfig maintenanceConfig1 = maintenanceConfigList.get(1);
                MaintenanceConfig maintenanceConfig2 = maintenanceConfigList.get(2);
                Double maintenanceConfigRange1_1 = maintenanceConfig1.getMaintenanceConfigRange1();
                Double maintenanceConfigRange1_2 = maintenanceConfig1.getMaintenanceConfigRange2();
                Double maintenanceConfigRange2_1 = maintenanceConfig2.getMaintenanceConfigRange1();

                Integer ageCloseFlag = 1;
                PcbaDevice pcbaDevice = pcbaDeviceDao.getById(pcbaDeviceId);
                if (pcbaDevice.getProductTime() != null && !"".equals(pcbaDevice.getProductTime().toString())) {
                    Date d1 = new Date();
                    LocalDate ld1 = d1.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                    LocalDate ld2 = pcbaDevice.getProductTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                    double age = CommonUtils.calculateYearDifference(ld2, ld1);

                    if (age >= maintenanceConfigRange1_1 && age < maintenanceConfigRange1_2) {
                        ageCloseFlag = 1;
                    }
                    if (age >= maintenanceConfigRange2_1) {
                        ageCloseFlag = 2;
                    }
                }

                if(ageCloseStatus == 1){
                    Integer integer = pcbaDeviceDao.handleAgeLoopCloseOk(pcbaDeviceId, ageCloseStatus, Integer.parseInt(userId), time, ageCloseFlag, ageCloseAuditReason);
                    if (integer > 0) {
                        /*DeviceAgeHistory addDeviceAgeHistory = new DeviceAgeHistory();
                        addDeviceAgeHistory.setAuditorId(Integer.parseInt(userId));
                        addDeviceAgeHistory.setAuditStatus(ageCloseStatus);
                        addDeviceAgeHistory.setCreateTime(new Date());
                        addDeviceAgeHistory.setPcbaDeviceId(pcbaDeviceId);
                        addDeviceAgeHistory.setCloseAuditReason(ageCloseAuditReason);
                        addDeviceAgeHistory.setType(2);
                        deviceAgeHistoryDao.addDeviceAgeHistory(addDeviceAgeHistory);*/
                        // 不能新增历史记录，需要根据流程uuid update
                        List<DeviceAgeHistory> deviceAgeHistories = deviceAgeHistoryDao.getByTypeAndUuid(2, pcbaDevice.getAgeCloseUuid());
                        for (DeviceAgeHistory deviceAgeHistory : deviceAgeHistories) {
                            deviceAgeHistory.setUpdateTime(d);
                            deviceAgeHistory.setCloseAuditReason(ageCloseAuditReason);
                            deviceAgeHistory.setAuditStatus(ageCloseStatus);
                            deviceAgeHistory.setAuditorId(Integer.parseInt(userId));
                            deviceAgeHistoryDao.updateDeviceAgeHistory(deviceAgeHistory);
                        }
                        /*1：挂起审核通过
                        2：挂起审核中
                        3：挂起审核拒绝
                        4：关闭审核通过
                        5：关闭审核中
                        6：关闭审核拒绝*/
                        // 审核通过 ，需要查询 loopCloseMethod 的值，
                        // 如果 ageCloseMethod = 1，修改 tb_pcba_device_age_handled 的 age_handled_status 的状态 = 1(挂起审核通过)
                        // 如果 ageCloseMethod = 2，修改 tb_pcba_device_age_handled 的 age_handled_status 的状态 = 4(关闭审核通过)
                        PcbaDeviceAgeHandled pcbaDeviceAgeHandled = pcbaDeviceAgeHandledDao.getById(pcbaDeviceId);
                        if(pcbaDeviceAgeHandled != null){
                            pcbaDeviceAgeHandled.setAgeHandledStatus(
                                    pcbaDevice.getAgeCloseMethod() != null && pcbaDevice.getAgeCloseMethod().equals(1) ? 1 : 4
                            );
                            //pcbaDeviceAgeHandled.setAgeHandledStatus(pcbaDevice.getAgeCloseMethod() != null ? (pcbaDevice.getAgeCloseMethod() == 1 ? 1 : 4) : 1);
                            pcbaDeviceAgeHandledDao.updatePcbaDeviceAgeHandled(pcbaDeviceAgeHandled);
                        }
                    }
                }else{
                    Integer integer = pcbaDeviceDao.handleAgeLoopCloseNo(pcbaDeviceId, ageCloseStatus, ageCloseAuditReason);
                    if (integer > 0) {
                        /*DeviceAgeHistory addDeviceAgeHistory = new DeviceAgeHistory();
                        addDeviceAgeHistory.setAuditorId(Integer.parseInt(userId));
                        addDeviceAgeHistory.setAuditStatus(ageCloseStatus);
                        addDeviceAgeHistory.setCreateTime(new Date());
                        addDeviceAgeHistory.setPcbaDeviceId(pcbaDeviceId);
                        addDeviceAgeHistory.setCloseAuditReason(ageCloseAuditReason);
                        addDeviceAgeHistory.setType(2);
                        deviceAgeHistoryDao.addDeviceAgeHistory(addDeviceAgeHistory);*/
                        // 不能新增历史记录，需要根据流程uuid update
                        List<DeviceAgeHistory> deviceAgeHistories = deviceAgeHistoryDao.getByTypeAndUuid(2, pcbaDevice.getAgeCloseUuid());
                        for (DeviceAgeHistory deviceAgeHistory : deviceAgeHistories) {
                            deviceAgeHistory.setUpdateTime(d);
                            deviceAgeHistory.setCloseAuditReason(ageCloseAuditReason);
                            deviceAgeHistory.setAuditStatus(ageCloseStatus);
                            deviceAgeHistory.setAuditorId(Integer.parseInt(userId));
                            deviceAgeHistoryDao.updateDeviceAgeHistory(deviceAgeHistory);
                        }
                        /*1：挂起审核通过
                        2：挂起审核中
                        3：挂起审核拒绝
                        4：关闭审核通过
                        5：关闭审核中
                        6：关闭审核拒绝*/
                        // 审核通过 ，需要查询 loopCloseMethod 的值，
                        // 如果 ageCloseMethod = 1，修改 tb_pcba_device_age_handled 的 age_handled_status 的状态 = 3(挂起审核拒绝)
                        // 如果 ageCloseMethod = 2，修改 tb_pcba_device_age_handled 的 age_handled_status 的状态 = 6(关闭审核拒绝)
                        PcbaDeviceAgeHandled pcbaDeviceAgeHandled = pcbaDeviceAgeHandledDao.getById(pcbaDeviceId);
                        if(pcbaDeviceAgeHandled != null){
                            Integer method = pcbaDevice.getAgeCloseMethod();
                            pcbaDeviceAgeHandled.setAgeHandledStatus(
                                    method != null && !method.equals(1) ? 6 : 3
                            );
                            //pcbaDeviceAgeHandled.setAgeHandledStatus(pcbaDevice.getAgeCloseMethod() != null ? (pcbaDevice.getAgeCloseMethod() == 1 ? 3 : 6) : 3);
                            pcbaDeviceAgeHandledDao.updatePcbaDeviceAgeHandled(pcbaDeviceAgeHandled);
                        }
                    }
                }
                return ResultUtil.success(null);
            } else {
                return ResultUtil.error(500, "年限预警配置不正确", "Config Error", null);
            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @Transactional(transactionManager = "MysqlTransactionManager1")
    @Override
    public Result goSubmitLoopClose(Integer pcbaDeviceId, Integer loopCloseMethod,String loopCloseRemark,String loopCloseFiles) {
        try{
            if(pcbaDeviceId == null || "".equals(pcbaDeviceId.toString())){
                return ResultUtil.error(500, "缺少参数pcbaDeviceId", "Miss param pcbaDeviceId", null);
            }
            if(loopCloseMethod == null || "".equals(loopCloseMethod.toString())){
                return ResultUtil.error(500, "缺少参数loopCloseMethod", "Miss param loopCloseMethod", null);
            }
            PcbaDevice pcbaDevice = pcbaDeviceDao.getById(pcbaDeviceId);
            String userId = UserHeaderHolder.getUserId();
            Date date = new Date();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
            String formattedDate = dateFormat.format(date);
            String uuid = formattedDate + "_" + UUID.randomUUID().toString();
            Integer integer = pcbaDeviceDao.goSubmitLoopClose(pcbaDeviceId, loopCloseMethod, loopCloseRemark, loopCloseFiles, uuid);
            if (integer > 0) {
                /**
                 * 添加到 记录表
                 */
                DeviceAgeHistory addDeviceAgeHistory = new DeviceAgeHistory();
                addDeviceAgeHistory.setSubmitterId(Integer.parseInt(userId));
                addDeviceAgeHistory.setAuditStatus(3);
                addDeviceAgeHistory.setCreateTime(new Date());
                addDeviceAgeHistory.setPcbaDeviceId(pcbaDeviceId);
                addDeviceAgeHistory.setCloseFiles(loopCloseFiles);
                addDeviceAgeHistory.setCloseRemark(loopCloseRemark);
                addDeviceAgeHistory.setCloseMethod(loopCloseMethod);
                addDeviceAgeHistory.setCloseUuid(uuid);
                addDeviceAgeHistory.setType(1);
                deviceAgeHistoryDao.addDeviceAgeHistory(addDeviceAgeHistory);
            }
            // 同步保存到 tb_pcba_device_age_handled，先判断有没有
            PcbaDeviceAgeHandled pcbaDeviceAgeHandled = pcbaDeviceAgeHandledDao.getById(pcbaDeviceId);
            if(pcbaDeviceAgeHandled == null){
                // add
                PcbaDeviceAgeHandled addPcbaDeviceAgeHandled = new PcbaDeviceAgeHandled();
                addPcbaDeviceAgeHandled.setPcbaDeviceId(pcbaDevice.getPcbaDeviceId());
                addPcbaDeviceAgeHandled.setPcbaDeviceNameCn(pcbaDevice.getPcbaDeviceNameCn());
                addPcbaDeviceAgeHandled.setPcbaDeviceNameEn(pcbaDevice.getPcbaDeviceNameEn());
                addPcbaDeviceAgeHandled.setCreateTime(pcbaDevice.getCreateTime());
                addPcbaDeviceAgeHandled.setPcbaDeviceTypeId(pcbaDevice.getPcbaDeviceTypeId());
                addPcbaDeviceAgeHandled.setSort(pcbaDevice.getSort());
                addPcbaDeviceAgeHandled.setPcbaLineId(pcbaDevice.getPcbaLineId());
                addPcbaDeviceAgeHandled.setPcbaDeviceResourceId(pcbaDevice.getPcbaDeviceResourceId());
                addPcbaDeviceAgeHandled.setAssetNumber(pcbaDevice.getAssetNumber());
                addPcbaDeviceAgeHandled.setProductTime(pcbaDevice.getProductTime());
                addPcbaDeviceAgeHandled.setPurpose(pcbaDevice.getPurpose());
                addPcbaDeviceAgeHandled.setLoopHandledStatus(loopCloseMethod == 1 ? 2 : 5);
                addPcbaDeviceAgeHandled.setAgeHandledStatus(null);
                pcbaDeviceAgeHandledDao.addPcbaDeviceAgeHandled(addPcbaDeviceAgeHandled);
            }else{
                pcbaDeviceAgeHandled.setLoopHandledStatus(loopCloseMethod == 1 ? 2 : 5);
                // update
                pcbaDeviceAgeHandledDao.updatePcbaDeviceAgeHandled(pcbaDeviceAgeHandled);
            }
            return ResultUtil.success(null);
        }catch (Exception e){
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @Transactional(transactionManager = "MysqlTransactionManager1")
    @Override
    public Result goSubmitAgeClose(Integer pcbaDeviceId, Integer ageCloseMethod, String ageCloseRemark, String ageCloseFiles) {
        try{
            if(pcbaDeviceId == null || "".equals(pcbaDeviceId.toString())){
                return ResultUtil.error(500, "缺少参数pcbaDeviceId", "Miss param pcbaDeviceId", null);
            }
            if(ageCloseMethod == null || "".equals(ageCloseMethod.toString())){
                return ResultUtil.error(500, "缺少参数ageCloseMethod", "Miss param ageCloseMethod", null);
            }
            PcbaDevice pcbaDevice = pcbaDeviceDao.getById(pcbaDeviceId);
            String userId = UserHeaderHolder.getUserId();
            Date date = new Date();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
            String formattedDate = dateFormat.format(date);
            String uuid = formattedDate + "_" + UUID.randomUUID().toString();
            Integer integer = pcbaDeviceDao.goSubmitAgeClose(pcbaDeviceId, ageCloseMethod, ageCloseRemark, ageCloseFiles, uuid);
            if (integer > 0) {
                DeviceAgeHistory addDeviceAgeHistory = new DeviceAgeHistory();
                addDeviceAgeHistory.setSubmitterId(Integer.parseInt(userId));
                addDeviceAgeHistory.setAuditStatus(3);
                addDeviceAgeHistory.setCreateTime(new Date());
                addDeviceAgeHistory.setPcbaDeviceId(pcbaDeviceId);
                addDeviceAgeHistory.setCloseFiles(ageCloseFiles);
                addDeviceAgeHistory.setCloseRemark(ageCloseRemark);
                addDeviceAgeHistory.setCloseMethod(ageCloseMethod);
                addDeviceAgeHistory.setCloseUuid(uuid);
                addDeviceAgeHistory.setType(2);
                deviceAgeHistoryDao.addDeviceAgeHistory(addDeviceAgeHistory);
            }
            // 同步保存到 tb_pcba_device_age_handled，先判断有没有
            PcbaDeviceAgeHandled pcbaDeviceAgeHandled = pcbaDeviceAgeHandledDao.getById(pcbaDeviceId);
            if(pcbaDeviceAgeHandled == null){
                // add
                PcbaDeviceAgeHandled addPcbaDeviceAgeHandled = new PcbaDeviceAgeHandled();
                addPcbaDeviceAgeHandled.setPcbaDeviceId(pcbaDevice.getPcbaDeviceId());
                addPcbaDeviceAgeHandled.setPcbaDeviceNameCn(pcbaDevice.getPcbaDeviceNameCn());
                addPcbaDeviceAgeHandled.setPcbaDeviceNameEn(pcbaDevice.getPcbaDeviceNameEn());
                addPcbaDeviceAgeHandled.setCreateTime(pcbaDevice.getCreateTime());
                addPcbaDeviceAgeHandled.setPcbaDeviceTypeId(pcbaDevice.getPcbaDeviceTypeId());
                addPcbaDeviceAgeHandled.setSort(pcbaDevice.getSort());
                addPcbaDeviceAgeHandled.setPcbaLineId(pcbaDevice.getPcbaLineId());
                addPcbaDeviceAgeHandled.setPcbaDeviceResourceId(pcbaDevice.getPcbaDeviceResourceId());
                addPcbaDeviceAgeHandled.setAssetNumber(pcbaDevice.getAssetNumber());
                addPcbaDeviceAgeHandled.setProductTime(pcbaDevice.getProductTime());
                addPcbaDeviceAgeHandled.setPurpose(pcbaDevice.getPurpose());
                addPcbaDeviceAgeHandled.setLoopHandledStatus(null);
                addPcbaDeviceAgeHandled.setAgeHandledStatus(ageCloseMethod == 1 ? 2 : 5);
                pcbaDeviceAgeHandledDao.addPcbaDeviceAgeHandled(addPcbaDeviceAgeHandled);
            }else{
                // update
                pcbaDeviceAgeHandled.setAgeHandledStatus(ageCloseMethod == 1 ? 2 : 5);
                // update
                pcbaDeviceAgeHandledDao.updatePcbaDeviceAgeHandled(pcbaDeviceAgeHandled);
            }
            return ResultUtil.success(null);
        }catch (Exception e){
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @Override
    public Result queryAllAssetNumberDevices(String chooseCompanyAndWorkshop, String assetNumber, Integer handledType, Integer pcbaDeviceTypeId, Integer brandId, Integer brandTypeId, Integer page, Integer pageSize) {
        try{

            int begin = (page - 1) * pageSize;

            List<Integer> pcbaWorkshopIdList = new ArrayList<>();
            if (chooseCompanyAndWorkshop != null && !"".equals(chooseCompanyAndWorkshop)) {
                JSONArray jsonArray = JSONArray.parseArray(chooseCompanyAndWorkshop);
                for (int a = 0; a < jsonArray.size(); a++) {
                    JSONArray jsonArray1 = jsonArray.getJSONArray(a);
                    if (jsonArray1.size() == 2) {
                        pcbaWorkshopIdList.add(jsonArray1.getInteger(1));
                    }
                }
            }

            Double dayOfHighLine = 6 * 365d;
            Double dayOfDevice = 6 * 365d;
            List<MaintenanceConfig> maintenanceConfigByType1 = maintenanceConfigDao.getMaintenanceConfigByType(1);
            if(maintenanceConfigByType1.size() > 0){
                dayOfHighLine = maintenanceConfigByType1.get(0).getMaintenanceConfigRange2() * 365d;
            }
            List<MaintenanceConfig> maintenanceConfigByType2 = maintenanceConfigDao.getMaintenanceConfigByType(2);
            if(maintenanceConfigByType2.size() > 0){
                dayOfDevice = maintenanceConfigByType2.get(0).getForewarningAge() * 365d;
            }
            List<PcbaDevice> list = pcbaDeviceDao.queryAllAssetNumberDevices(assetNumber, handledType, dayOfHighLine, dayOfDevice, pcbaDeviceTypeId, pcbaWorkshopIdList, begin, pageSize);
            List<PcbaDevice> list2 = pcbaDeviceDao.queryAllAssetNumberDevices(assetNumber, handledType, dayOfHighLine, dayOfDevice, pcbaDeviceTypeId, pcbaWorkshopIdList, null, null);
            for (PcbaDevice pcbaDevice : list) {
                if (pcbaDevice.getProductTime() != null && !"".equals(pcbaDevice.getProductTime().toString())) {
                    Date d1 = new Date();
                    LocalDate ld1 = d1.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                    LocalDate ld2 = pcbaDevice.getProductTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                    double age = CommonUtils.calculateYearDifference(ld2, ld1);
                    pcbaDevice.setAge(age);
                }
                Integer pcbaLineId = pcbaDevice.getPcbaLineId();
                if(pcbaLineId != null){
                    PcbaLine pcbaLineById = pcbaLineDao.getPcbaLineById(pcbaLineId);
                    if(pcbaLineById != null){
                        pcbaLineById.setPcbaCompany(pcbaCompanyDao.getPcbaCompanyById(pcbaLineById.getPcbaCompanyId()));
                        pcbaLineById.setPcbaWorkshop(pcbaWorkshopDao.getPcbaWorkshopById(pcbaLineById.getPcbaWorkshopId()));
                        pcbaDevice.setPcbaLine(pcbaLineById);
                    }
                }
                Integer pcbaDeviceId = pcbaDevice.getPcbaDeviceId();
                if(pcbaDeviceId != null){
                    List<DeviceAgeHistory> deviceAgeHistoryByDeviceId1 = deviceAgeHistoryDao.getDeviceAgeHistoryByDeviceId(pcbaDeviceId, 1);
                    for (DeviceAgeHistory deviceAgeHistory : deviceAgeHistoryByDeviceId1) {
                        Integer submitterId = deviceAgeHistory.getSubmitterId();
                        if(submitterId != null){
                            deviceAgeHistory.setSubmitter(userDao.getUserInfoById(submitterId));
                        }
                        Integer auditorId = deviceAgeHistory.getAuditorId();
                        if(auditorId != null){
                            deviceAgeHistory.setAuditor(userDao.getUserInfoById(auditorId));
                        }
                        List<String> closeFilesList = new ArrayList<>();
                        if(deviceAgeHistory.getCloseFiles() != null && !"".equals(deviceAgeHistory.getCloseFiles())){
                            String[] split = deviceAgeHistory.getCloseFiles().split(",");
                            closeFilesList.addAll(Arrays.asList(split));
                        }
                        deviceAgeHistory.setCloseFilesList(closeFilesList);
                    }
                    pcbaDevice.setDeviceAgeHistoryListOfHighLine(deviceAgeHistoryByDeviceId1);
                    List<DeviceAgeHistory> deviceAgeHistoryByDeviceId2 = deviceAgeHistoryDao.getDeviceAgeHistoryByDeviceId(pcbaDeviceId, 2);
                    for (DeviceAgeHistory deviceAgeHistory : deviceAgeHistoryByDeviceId2) {
                        Integer submitterId = deviceAgeHistory.getSubmitterId();
                        if(submitterId != null){
                            deviceAgeHistory.setSubmitter(userDao.getUserInfoById(submitterId));
                        }
                        Integer auditorId = deviceAgeHistory.getAuditorId();
                        if(auditorId != null){
                            deviceAgeHistory.setAuditor(userDao.getUserInfoById(auditorId));
                        }
                        List<String> closeFilesList = new ArrayList<>();
                        if(deviceAgeHistory.getCloseFiles() != null && !"".equals(deviceAgeHistory.getCloseFiles())){
                            String[] split = deviceAgeHistory.getCloseFiles().split(",");
                            closeFilesList.addAll(Arrays.asList(split));
                        }
                        deviceAgeHistory.setCloseFilesList(closeFilesList);
                    }
                    pcbaDevice.setDeviceAgeHistoryListOfCommonLine(deviceAgeHistoryByDeviceId2);
                }
                Integer pcbaDeviceTypeId_ = pcbaDevice.getPcbaDeviceTypeId();
                if(pcbaDeviceTypeId_ != null){
                    PcbaDeviceType byId = pcbaDeviceTypeDao.getById(pcbaDeviceTypeId_);
                    if(byId != null){
                        pcbaDevice.setPcbaDeviceType(byId);
                    }
                }
                Integer pcbaDeviceResourceId = pcbaDevice.getPcbaDeviceResourceId();
                if(pcbaDeviceResourceId != null){
                    PcbaDeviceResource byId = pcbaDeviceResourceDao.getById(pcbaDeviceResourceId);
                    if(byId != null){
                        Integer brandId_ = byId.getBrandId();
                        if(brandId_ != null){
                            Brand brandById = brandDao.getBrandById(brandId_);
                            if(brandById != null){
                                byId.setBrand(brandById);
                            }
                        }
                        Integer brandTypeId_ = byId.getBrandTypeId();
                        if(brandTypeId_ != null){
                            BrandType brandTypeById = brandTypeDao.getBrandTypeById(brandTypeId_);
                            if(brandTypeById != null){
                                byId.setBrandType(brandTypeById);
                            }
                        }
                        pcbaDevice.setPcbaDeviceResource(byId);
                    }
                }
            }
            /*// 进一步过滤，注意筛选条件为空的情况
            if(pcbaWorkshopIdList.size() == 0){
                return ResultUtil.tableSuccess(page, pageSize, list2.size(), list);
            }
            List<PcbaDevice> finalList = new ArrayList<>();
            for (PcbaDevice pcbaDevice : list) {
                if(pcbaDevice.getPcbaLine() != null && pcbaDevice.getPcbaLine().getPcbaWorkshopId() != null){
                    if(pcbaWorkshopIdList.contains(pcbaDevice.getPcbaLine().getPcbaWorkshopId().toString())){
                        finalList.add(pcbaDevice);
                    }
                }
            }
            return ResultUtil.tableSuccess(page, pageSize, list2.size(), finalList);*/
            return ResultUtil.tableSuccess(page, pageSize, list2.size(), list);
        }catch (Exception e){
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @Transactional(transactionManager = "MysqlTransactionManager1")
    @Override
    public Result addDeviceAuditHistory(Integer pcbaDeviceId, Integer type, Integer closeMethod, String closeRemark, String closeFiles) {
        try{
            if(pcbaDeviceId == null || "".equals(pcbaDeviceId.toString())){
                return ResultUtil.error(500, "缺少参数pcbaDeviceId", "Miss param pcbaDeviceId", null);
            }
            if(type == null || "".equals(type.toString())){
                return ResultUtil.error(500, "缺少参数type", "Miss param type", null);
            }
            String userId = UserHeaderHolder.getUserId();
            DeviceAgeHistory addDeviceAgeHistory = new DeviceAgeHistory();
            addDeviceAgeHistory.setPcbaDeviceId(pcbaDeviceId);
            addDeviceAgeHistory.setType(type);
            addDeviceAgeHistory.setCreateTime(new Date());
            addDeviceAgeHistory.setAuditStatus(1);
            addDeviceAgeHistory.setCloseRemark(closeRemark);
            addDeviceAgeHistory.setCloseFiles(closeFiles);
            addDeviceAgeHistory.setAuditorId(Integer.parseInt(userId));
            addDeviceAgeHistory.setSubmitterId(Integer.parseInt(userId));
            addDeviceAgeHistory.setCloseMethod(closeMethod);
            deviceAgeHistoryDao.addDeviceAgeHistory(addDeviceAgeHistory);

            // 修改 审核状态
            PcbaDeviceAgeHandled updatePcbaDeviceAgeHandled = pcbaDeviceAgeHandledDao.getById(pcbaDeviceId);
            if(type == 1){
                updatePcbaDeviceAgeHandled.setLoopHandledStatus(4);
            }else{
                updatePcbaDeviceAgeHandled.setAgeHandledStatus(4);
            }
            pcbaDeviceAgeHandledDao.updatePcbaDeviceAgeHandled(updatePcbaDeviceAgeHandled);

            return ResultUtil.success(null);
        }catch (Exception e){
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    /*@Transactional(transactionManager = "MysqlTransactionManager1")
    @Override
    public Result addOrUpdateDeviceAndParamRelated(String data) {
        try{
            JSONObject jsonObject = JSONObject.parseObject(data);
            String mode = jsonObject.getString("mode");
            JSONArray jsonArray = jsonObject.getJSONArray("pcbaDeviceRelatedDeviceParamList");
            Date d = new Date();
            if("add".equals(mode)){
                // 新增pcbaDevice
                PcbaDevice pcbaDevice = new PcbaDevice();
                pcbaDevice.setPcbaDeviceNameCn(jsonObject.get("pcbaDeviceNameCn").toString());
                pcbaDevice.setPcbaDeviceNameEn(jsonObject.get("pcbaDeviceNameEn").toString());
                pcbaDevice.setStatus(Integer.parseInt(jsonObject.get("status").toString()));
                pcbaDevice.setSort(Integer.parseInt(jsonObject.get("sort").toString()));
                pcbaDevice.setPcbaDeviceTypeId(Integer.parseInt(jsonObject.get("pcbaDeviceTypeId").toString()));
                pcbaDevice.setCreateTime(d);
                pcbaDevice.setCompanyId(Integer.parseInt(jsonObject.get("company").toString()));// 当前将这个写死，后面动态
                pcbaDeviceDao.addPcbaDevice(pcbaDevice);
                // 新增pcbaDeviceRelatedDeviceParam
                for(int a = 0;a<jsonArray.size();a++){
                    JSONObject jo = (JSONObject)jsonArray.get(a);
                    PcbaDeviceRelatedDeviceParam pcbaDeviceRelatedDeviceParam = new PcbaDeviceRelatedDeviceParam();
                    pcbaDeviceRelatedDeviceParam.setCreateTime(d);
                    // 获取上面自增的id
                    pcbaDeviceRelatedDeviceParam.setPcbaDeviceResourceId(pcbaDevice.getPcbaDeviceId());
                    pcbaDeviceRelatedDeviceParam.setCreateTime(d);
                    pcbaDeviceRelatedDeviceParam.setPcbaDeviceParamKey(jo.get("pcbaDeviceParamKey").toString());
                    pcbaDeviceRelatedDeviceParam.setPcbaDeviceTypeId(Integer.parseInt(jo.get("pcbaDeviceTypeId").toString()));
                    pcbaDeviceRelatedDeviceParam.setPcbaDeviceParamValue(jo.get("pcbaDeviceParamValue").toString());
                    pcbaDeviceRelatedDeviceParamDao.addDeviceRelatedParam(pcbaDeviceRelatedDeviceParam);
                }
                return ResultUtil.success(null);
            }else if("update".equals(mode)){
                Integer pcbaDeviceId = jsonObject.getInteger("pcbaDeviceId");
                if(pcbaDeviceId == null || "".equals(pcbaDeviceId.toString())){
                    return ResultUtil.error(500, "缺少参数pcbaDeviceId", "Miss Param pcbaDeviceId", null);
                }
                PcbaDevice pcbaDevice = new PcbaDevice();
                pcbaDevice.setPcbaDeviceNameCn(jsonObject.get("pcbaDeviceNameCn").toString());
                pcbaDevice.setPcbaDeviceNameEn(jsonObject.get("pcbaDeviceNameEn").toString());
                pcbaDevice.setStatus(Integer.parseInt(jsonObject.get("status").toString()));
                pcbaDevice.setSort(Integer.parseInt(jsonObject.get("sort").toString()));
                pcbaDevice.setPcbaDeviceTypeId(Integer.parseInt(jsonObject.get("pcbaDeviceTypeId").toString()));
                pcbaDevice.setUpdateTime(d);
                pcbaDevice.setCompanyId(Integer.parseInt(jsonObject.get("company").toString()));// 当前将这个写死，后面动态
                pcbaDevice.setPcbaDeviceId(pcbaDeviceId);
                pcbaDeviceDao.updatePcbaDevice(pcbaDevice);

                //根据deviceId删除关联
                pcbaDeviceRelatedDeviceParamDao.deleteDeviceRelatedParam(pcbaDeviceId);

                // 新增pcbaDeviceRelatedDeviceParam
                for(int a = 0;a<jsonArray.size();a++){
                    JSONObject jo = (JSONObject)jsonArray.get(a);
                    PcbaDeviceRelatedDeviceParam pcbaDeviceRelatedDeviceParam = new PcbaDeviceRelatedDeviceParam();
                    pcbaDeviceRelatedDeviceParam.setCreateTime(d);
                    // 获取上面自增的id
                    //pcbaDeviceRelatedDeviceParam.setPcbaDeviceId(pcbaDevice.getPcbaDeviceId());
                    pcbaDeviceRelatedDeviceParam.setCreateTime(d);
                    pcbaDeviceRelatedDeviceParam.setPcbaDeviceParamKey(jo.get("pcbaDeviceParamKey").toString());
                    pcbaDeviceRelatedDeviceParam.setPcbaDeviceTypeId(pcbaDeviceId);
                    pcbaDeviceRelatedDeviceParam.setPcbaDeviceParamValue(jo.get("pcbaDeviceParamValue").toString());
                    pcbaDeviceRelatedDeviceParamDao.addDeviceRelatedParam(pcbaDeviceRelatedDeviceParam);
                }
                return ResultUtil.success(null);
            }
            return ResultUtil.error(500, "mode 参数错误", "Error Param mode", null);
        }catch (Exception e){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }*/
}
